MyBatisPlus(三)CRUD接口操作

2023-05-16

一、CRUD扩展

Insert 插入

// 测试插入
@Test
public void testInsert(){
    User user = new User();
    user.setName("tom");
    user.setAge(2);
    user.setEmail("1097597579@qq.com");

    int result = userMapper.insert(user);// 帮我们自动生成id
    System.out.println(result);// 受影响的行数
    System.out.println(user);// 会发现 id 自动回填
}

在这里插入图片描述
数据库插入的id的默认值为:全局的唯一id

主键生成策略

分布式系统唯一id 生成:https://www.cnblogs.com/haoxinyue/p/5208136.html

策略主要有

  • 自动增长
  • UUID
  • redis实现
  • snowflake算法

MyBatisPlus默认 ID_WORKER 全局唯一id

// 对应数据库中的主键(uuid、自增id、雪花算法,redis、zookeeper)
@TableId(type = IdType.ID_WORKER)
private Long id;

雪花算法:

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。

主键自增

我们需要配置主键自增:

1、实体属性字段上@TableId(type = IdType.AUTO)

2、数据库字段一定要为自增。否则会报错。
在这里插入图片描述
3、再次测试插入可以看出结果
在这里插入图片描述

其他的源码解释:

public enum IdType {
    AUTO(0),// 数据库id自增
    NONE(1),// 未设置主键
    INPUT(2),// 手动输入
    ID_WORKER(3),// 默认的全局唯一id,mp自带策略,生成19位的值,数字类型可以使用这个策略
    UUID(4),// 全局唯一uuid
    ID_WORKER_STR(5);// 字符串类型可以使用这个策略

    private int key;

    private IdType(int key) {
        this.key = key;
    }

    public int getKey() {
        return this.key;
    }
}

更新操作

// 测试更新
    @Test
    public void testUpdate(){
        User user = new User();
        // 通过条件动拼接动态SQL
        user.setId(6L);
        user.setName("lisi");
        user.setAge(15);

        // 注意:updateById 但是参数是一个 对象。
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

在这里插入图片描述
所有SQL都是自动帮你动态配置的。

自动填充

创建时间、修改时间。这些操作一遍都是自动完成的,我们不希望手动更新。

阿里巴巴手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上。而且需要自动化。

方式一: 数据库级别(工作中不建议)

1、在表中新增字段:create_time、update_time
在这里插入图片描述
2、同步实体类

private Date createTime;
private Date updateTime;

3、测试更新操作
在这里插入图片描述

方式二:代码级别

1、删除数据库的默认值。
在这里插入图片描述
2、在实体类字段属性上添加注解

// 字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

3、编写处理器来处理这个注解

@Slf4j
@Component// 一定不要忘记吧处理器加入到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill....");
        // default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    // 更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

4、测试插入,观察时间即可。

5、测试更新,观察时间即可。
在这里插入图片描述

乐观锁

在面试中经常会被问道乐观锁、悲观锁。

乐观锁:顾名思意十分乐观,他总是认为不会出现问题,无论干什么都不去上锁。如果出现问题,就在再次更新值测试。
悲观锁:顾名思意十分悲观,他总是认为总是出现问题,无论干什么都会上锁,在去操作。

这里主要说乐观锁机制!乐观锁主要解决丢失更新问题

丢失更新:多个人同时修改同一条记录,最后提交的把之前的提交数据覆盖。

乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败
乐观锁:先查询版本号 version = 1
--A线程
update user set name ="starsea7",version = version +1
where id = 2 and version = 1

--B线程 抢先完成,这个时候 version = 2 ,会导致A修改失败。
update user set name ="starsea7",version = version +1
where id = 2 and version = 1

测试一下MP的乐观锁插件

1、给数据库中增加一个version字段

在这里插入图片描述
2、给实体类加对应字段

//@TableField(fill = FieldFill.INSERT)
@Version//乐观锁Version注解
private Integer version;

3、注册组件

// 添加 @MapperScan 注解,扫描 Mapper 文件夹
@MapperScan("com.kuang.mapper")
@EnableTransactionManagement
@Configuration//配置类
public class MyBatisPlusConfig {
    //注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

4、测试乐观锁

// 测试乐观锁成功
@Test
 public void testOptimisticLocker(){
     // 查询用户信息
     User user = userMapper.selectById(1L);
     //修改用户信息
     user.setName("starsea7");
     user.setEmail("1065510476@qq.com");
     // 执行更新操作
     userMapper.updateById(user);
 }

 // 测试乐观锁失败,多线程下
 @Test
 public void testOptimisticLocker2(){
     // 线程1
     User user = userMapper.selectById(1L);
     user.setName("starsea77");
     user.setEmail("1065510476@qq.com");

     // 线程2
     User user2 = userMapper.selectById(1L);
     user2.setName("starsea88");
     user2.setEmail("1065510476@qq.com");
     userMapper.updateById(user2);

     // 自旋锁来多次尝试提交。
     userMapper.updateById(user);// 如果没有乐观锁就会覆盖插队线程的值
 }

在这里插入图片描述
·

查询操作

// 测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

// 测试批量查询
@Test
public void testSelectByBatchId(){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3, 4));
    users.forEach(System.out::println);
}

// 条件查询之一使用 map
@Test
public void testSelectByBatchIds(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","tom");
    map.put("age",2);

    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

分页查询

分页在网站使用非常之多!

1、使用原始的 limit 进行分页

2、pageHelper 第三方插件

3、MP 其实也内置了分页插件

如何使用

1、配置拦截器组件即可

//分页插件
@Bean
 public PaginationInterceptor paginationInterceptor(){
     return new PaginationInterceptor();
 }

2、直接使用page对象即可

// 测试分页查询
@Test
public void testPage(){
    // 参数一:当前页
    // 参数二:页面大小
    Page<User> page = new Page<>(1,5);
    userMapper.selectPage(page,null);

    page.getRecords().forEach(System.out::println);
    System.out.println(page.getTotal());//总记录数
    System.out.println(page.getCurrent());//当前页
    System.out.println(page.getRecords());//每页数据list集合
    System.out.println(page.getSize());//每页显示记录数
    System.out.println(page.getPages());//总页数
    
    System.out.println(page.hasNext());//下一页
    System.out.println(page.hasPrevious());//上一页
}

删除操作

基本删除操作

// 测试删除
@Test
 public void testDeleteById(){
     int i = userMapper.deleteById(6L);
     System.out.println(i);
 }

 // 通过id批量删除
 @Test
 public void testDeleteBatchId(){
     int i = userMapper.deleteBatchIds(Arrays.asList(1294578792320237570L, 1294578792320237571L, 1294578792320237572L));
     System.out.println(i);
 }

 // 通过 map 条件删除
 @Test
 public void testDeleteMap(){
     HashMap<String, Object> map = new HashMap<>();
     map.put("name","zhangsan");

     userMapper.deleteByMap(map);
 }

我们在工作中遇到一些问题:逻辑删除

逻辑删除

物理删除:从数据库中直接删除
逻辑删除:在数据库中没有移除,而是通过一个变量来让他失效,deleted = 0 => deleted = 1

应用场景:管理员可以查询被删除的记录!方式数据的丢失,类似于回收站。

测试一下:

1、在数据表中增加 一个 deleted 字段

在这里插入图片描述
2、实体类中增加属性

@TableLogic// 逻辑删除
private Integer deleted;

3、配置组件

//逻辑删除组件
@Bean
public ISqlInjector sqlInjector(){
    return  new LogicSqlInjector();
}

4、逻辑删除的配置

# 配置逻辑删除,默认值
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

5、测试删除操作

在这里插入图片描述

记录依旧在数据库,但是值确已变化了。

在这里插入图片描述

在次查询这条数据,发现过滤了逻辑删除的数据。

在这里插入图片描述

以上就是所有的CRUD 操作及其扩展的操作。 会大大提高你的工作效率和写项目的效率。


如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatisPlus(三)CRUD接口操作 的相关文章

  • MyBatis-Plus:条件构造器Wrapper

    目录 1 Wrapper概述 1 1 Wrapper的继承关系 1 2 Wapper介绍 1 3 各个构造器使用区别 1 4 构造器常用方法 2 Wrapper常用构造器介绍 2 1 QueryWrapper 2 2 UpdateWrapp
  • MyBatis-Plus是什么?为什么用?怎么用?

    1 MyBatis Plus是什么 官方是这样定义的 Mybatis Plus 简称MP 是一个 Mybatis 的增强工具 在 Mybatis 的基础上只做增强不做改变 为简化开发 提高效率而生 所谓的增强 就是已经封装好了一些crud
  • mybatis-plus 新增/修改实现自动填充指定字段

    需要修改的字段在模型类上添加 TableField fill FieldFill xxx 注解 FieldFill的选项 哪个字段在什么时候填充需要手动设置注解 新建一个MetaObjectHandler的实现类MyMetaObjectHa
  • 【MyBatis-Plus】之批量插入

    一 应用情景介绍 在实际的项目开发过程中 常常遇到批量保存数据的场景 当数据量比较少 比如只有几条数据的情况下 我们可以使用 for 循环来 insert 数据 但如果数据量比较多的情况下就不行 特别是并发的情况下 因为这样会增加数据库的负
  • SpringBoot-基础篇复习(全)

    本文包含SpringBoot基础篇的所有知识点 大家一起来学习吧 开启一段新的旅程 加油吧 springboot是由Picotal团队提供的全新框架 用来简化spring的搭建和开发过程的配置 因为spring的配置比较繁琐 故引入了spr
  • 为啥MyBatis-Plus 分页插件不生效?

    描述 项目中用到boot 整合 mybatis plus 个人在使用分页条件查询的时候一直查不出 total pages 终于找到原因了 环境
  • FastAPI 服务器返回“422 无法处理的实体”- value_error.missing

    from http client import responses from random import randrange from tkinter tix import STATUS from typing import Optiona
  • Symfony 4 MakerBundle 自己的 Crud Maker

    我想定制新的makerbundle CRUD Maker的样板代码 不像在 SensioGeneratorBundle 中那样简单地覆盖模板 我尝试根据原始代码生成自定义 MyMakeCrud 但我对注入的 DoctrineEntityHe
  • Yii2 GridView实现外部表相关表的值过滤和排序

    我有 3 张表 CREATE TABLE tabCve intCveID INTEGER NOT NULL AUTO INCREMENT strNumber VARCHAR 20 NOT NULL fltScore FLOAT 0 strD
  • 是否有类似于 JTable 的预构建 Angular 组件?

    AngularJS 看起来是一个很棒的系统 但我对企业风格 CRUD 的预构建组件很好奇 JQueryUI有优秀的JTable 还有datatable和jqGrid 基本上 我想知道是否有一个自动表 具有服务器端 CRUD REST 后端支
  • PHP 和 Microsoft Access 数据库 - 连接和 CRUD

    我没有访问经验 如何使用和不使用更新 插入 删除 选择语句 rs new com ADODB RecordSet PDO 如果您想使用 PHP 与 MS Access 数据库交互 PDO http php net manual en boo
  • 在 Symfony2 中向删除表单添加“确认选项”的最佳方法是什么?

    如果您使用控制台为 Symfony2 中的实体创建 CRUD 代码 您最终将得到一个非常基本的删除功能 此功能简洁高效 但不提供 您确定吗 确认 如果要删除的实体存在 则立即删除 有人对添加用户确认的最简单方法有建议吗 到目前为止我一直在使
  • 在 Lithium 中调用 MySQL 函数

    如何调用 MySQL 函数 例如GeomFromText or 选择为 在里面锂框架 http www lithify me 增删改查 使用数据库 gt 读取 很不方便 我经常更改数据库列 并且将函数包含在变量的值中只会最终被转义 您是否尝
  • 我无法从 mongoDb ObjectId 类构造函数错误中删除数据

    我写了一个express index js来在mongodb中进行简单的增删改查操作 该项目是我可以 console log 作为 mongodb Id 的参数 但是 ObjectId 内置函数给了我一个类构造函数错误 如果没有 new 它
  • 使用 GET 而不是 POST 删除经过身份验证的页面后面的数据 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我知道只要在公共网站上修改数据 您就应该使用 POST 有几个原因 包括搜索引擎会跟踪所有链接并修改数据 我的问题是 您认为在管理界面等经过
  • 如何为 has_many_polymorphs 和错误设置这些 CRUD 控制器操作

    我正在使用有很多多态性 https github com fauna has many polymorphs插件 以便可以将视频 主题和用户发布到个人资料中 因此 一个个人资料有很多 showable objects 可以是视频 主题和用户
  • 我需要一个非常简单的 PHP 数据库前端管理面板;指定表的简单记录编辑器[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望为我们的公司网站添加一些动态 这是次要角色 所以我不想花太多时间在上面 此时 我所需要的只是一个简单的 PHP 脚本 非技术用户可以
  • 抽象 CRUD 控制器是个好主意吗?

    我们正在使用 ASP NET MVC 开发一个相当大的应用程序 一开始我们发现拥有一个具有常见 CRUD 操作 新建 保存 删除 以及默认列表操作的抽象基本控制器可能很有用 在我们的例子中 我们有 20 多个实体通过这种控制器进行管理 这有
  • 如何使用 BDD 构建 CRUD 测试

    我陷入了一个进退两难的境地 试图找出答案best构建我的 CRUD 测试的方式 在我的应用程序中 用户可以创建多种类型的 任务 我当前的实现如下所示 Scenario Create Task Type A Given I am on a u
  • 将策略应用到资源控制器

    我有一个CRUD资源定义通过Route resource User UserController 既然可以生成CRUDGates and Policies 有没有办法应用这样的Gate Policy 以便将相应的Gate Policy应用于

随机推荐

  • SpringCloud(一)微服务概述

    文章目录 微服务概述什么是微服务微服务与微服务架构微服务的优缺点优点缺点 微服务的技术栈为什么选SpringCloud作为微服务架构选型依据当前各大IT公司的微服务架构各微服务的框架对比 SpringCloud入门概述SpringCloud
  • SpringCloud(二)入门案例之支付模块与订单模块的调用

    SpringCloud xff08 一 xff09 微服务概述 xff1a https blog csdn net weixin 45606067 article details 108481733 构建SpringCloud工程 概述 x
  • SpringCloud(三)Eureka服务注册中心

    文章目录 1 Eureka基础知识什么是服务治理什么是服务注册Eureka两大组件 2 Eureka介绍及原理理解介绍原理 3 单机版Eureka 构建步骤4 集群版Eureka 构建步骤Eureka集群原理说明EurekaServer集群
  • SpringCloud(四)zookeeper介绍及原理

    SpringCloud xff08 四 xff09 zookeeper介绍及原理 xff1a https blog csdn net weixin 45606067 article details 108499344 Zookeeper服务
  • docker 的安装 - 常用命令 - 应用部署

    文章目录 1 Docker简介什么是虚拟化什么是Docker容器与虚拟化比较Docker 组件1 Docker服务器与客户端2 Docker镜像与容器3 Register xff08 注册中心 xff09 2 Docker安装与启动安装Do
  • SpringCloud(六)Ribbon负载均衡服务调用

    Ribbon负载均衡 概述 是什么 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡工具 简单的说 xff0c Ribbon是Netflix发布的开源项目 xff0c 主要功能是提供客户端的
  • Python:map()函数使用详解

    1 函数定义 xff1a map function iterable 2 作用 xff1a 该函数通过接收一个函数function作为处理函数 xff0c 然后接收一个参数序列iterable xff0c 并使用处理函数对序列中的每个元素逐
  • SpringCloud(五)Consul服务注册与发现

    SpringCloud xff08 四 xff09 zookeeper介绍及原理 xff1a https blog csdn net weixin 45606067 article details 108538357 Consul简介 是什
  • SpringCloud(七)OpenFeign负载均衡服务调用

    1 概述 1 OpenFeign是什么 官网解释 xff1a https cloud spring io spring cloud static Hoxton SR1 reference htmlsingle spring cloud op
  • Zookeeper概述 | 安装部署(Windows和Linux)

    Zookeeper 一 Zokeeper 门 1 概述 Zookeeper是一个开源的分布式的 xff0c 为分布式应用提供协调服务的Apache项目 ZooKeeper is a centralized service for maint
  • Zookeeper内部原理

    Zookeeper概述 安装部署 xff08 Windows和Linux xff09 xff1a https blog csdn net weixin 45606067 article details 108619378 1 选举机制 面试
  • jsp和servlet的区别

    基本介绍 Servlet xff1a Servlet 是一种服务器端的Java应用程序 xff0c 具有独立于平台和协议的特性 xff0c 可以生成动态的Web页面 它担当客户请求 xff08 Web浏览器或其他HTTP客户程序 xff09
  • Session学习笔记

    1 session 简介 session 是我们 jsp 九大隐含对象的一个对象 session 称作域对象 xff0c 他的作用是保存一些信息 xff0c 而 session 这个域对象是一次会话期间使用同一个对象 所以这个对象可以用来保
  • session和cookie 区别【面试】

    说说Cookie和Session的区别 xff1f 1 存取方式的不同 xff08 Cookie只能保存ASCII xff0c Session可以存任意数据类型 xff09 Cookie中只能保管ASCII字符串 xff0c 假如需求存取U
  • JSP 九大内置对象,四大域对象

    JSP的九大内置对象 内置对象名 类型 request HttpServletRequest response HttpServletResponse session HttpSession application ServletConte
  • SpringCloud(八)Hystrix断路器

    文章目录 1 概述分布式系统面临的问题是什么能干嘛官网资料Hystrix官宣 xff0c 停更进维 2 Hystrix重要概念3 hystrix案例构建项目高并发测试故障现象和导致原因上诉结论如何解决 xff1f 解决的要求服务降级服务熔断
  • 谷粒学院(一)项目介绍

    一 项目背景 在线教育顾名思义 xff0c 是以网络为介质的教学方式 xff0c 通过网络 xff0c 学员与教师即使相隔万里也可以开展教学活动 xff0c 此外 xff0c 借助网络课件 xff0c 学员还可以随时随地进行学习 xff0c
  • PyTorch:Dataset()与Dataloader()的使用详解

    目录 1 Dataset类的使用 2 Dataloader类的使用 3 总结 Dataset类与Dataloader类是PyTorch官方封装的用于在数据集中提取一个batch的训练用数据的接口 xff0c 其实我们也可以自定义获取每个ba
  • MyBatisPlus(二)入门案例

    一 快速入门 使用第三方组件 xff1a 导入对应的依赖研究依赖如何配置代码如何编写提高扩展技术能力 操作步骤 1 创建数据库mybatis plus 2 创建user表 span class token keyword DROP span
  • MyBatisPlus(三)CRUD接口操作

    一 CRUD扩展 Insert 插入 span class token comment 测试插入 span span class token annotation punctuation 64 Test span span class to