• [Mybatis-Plus笔记] MybatisPlus-05-id生成策略,多数据操作,逻辑删除


    一、id生成策略

    在实体类的 id 属性上注解 @TableId 并指定 type 属性,可以设置 id 生成策略,常用的有下面几种:

    1. 自增id(type = IdType.AUTO)

    注解 @TableId(type = IdType.AUTO) 表示为自增 id,需要表结构也将 id 设为自增主键

    自增 id 会按照顺序递增生成 id,插入数据时可以不带 id 值,也可以指定 id 值,但不能是已有的 id

    实体类:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @TableName("tbl_user")
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试类:

    @SpringBootTest
    public class MybatisPlusTest {
        @Autowired
        UserMapper userMapper;
        @Test
        void testInsert() {
            User user = new User(null, "Alice", 17, "alice@outlook.com");
            userMapper.insert(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Mybatis-Plus 日志:

    ==>  Preparing: INSERT INTO tbl_user ( name, age, email ) VALUES ( ?, ?, ? )
    ==> Parameters: Alice(String), 17(Integer), alice@outlook.com(String)
    <==    Updates: 1
    
    • 1
    • 2
    • 3

    2. 输入id(type = IdType.INPUT)

    注解 @TableId(type = IdType.INPUT) 表示需要插入数据时需要指定 id 值

    通常表结构中 id 不是自增主键,如果是自增的,那么无需指定 id 值也可正常插入,效果和 IdType.AUTO 相同

    实体类 id 字段:

    	// 省略了无关部分
        @TableId(type = IdType.INPUT)
        private Long id;
    
    • 1
    • 2
    • 3

    测试方法:

        @Test
        void testInsert() {
            User user = new User(37L, "Alice", 17, "alice@outlook.com");
            userMapper.insert(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Mybatis-Plus 日志:

    ==>  Preparing: INSERT INTO tbl_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
    ==> Parameters: 37(Long), Alice(String), 17(Integer), alice@outlook.com(String)
    <==    Updates: 1
    
    • 1
    • 2
    • 3

    2. 雪花算法生成id(type = IdType.ASSIGN_ID)

    注解 @TableId(type = IdType.ASSIGN_ID) ,表示由 Mybatis-Plus 自动生成 id 并填入数据库

    插入数据时不指定 id 值便会使用雪花算法自动生成的 id,若指定了 id 则不会

    实体类 id 字段:

    	// 省略了无关部分
        @TableId(type = IdType.ASSIGN_ID)
        private Long id;
    
    • 1
    • 2
    • 3

    测试方法:

        @Test
        void testInsert() {
            User user = new User(null, "Alice", 17, "alice@outlook.com");
            userMapper.insert(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Mybatis-Plus 日志:

    ==>  Preparing: INSERT INTO tbl_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
    ==> Parameters: 1571399057521795074(Long), Alice(String), 17(Integer), alice@outlook.com(String)
    <==    Updates: 1
    
    • 1
    • 2
    • 3

    雪花算法所生成的是一个 64 位的长整形,所以 id 通常用 Long 类型

    对应生成的长整型 id,简单来说从左到右分别为 1 位符号位,41 位时间戳(差值),10 位机器码,12 位序列号

    关于雪花算法,更详细的内容推荐阅读这篇文章:雪花算法(SnowFlake)

    二、多数据操作(查询与删除)

    1. 按多个 id 查询

    使用 selectBatchIds() 方法实现,将一个 List 作为参数传入,里面存放着多个 id

    测试方法:

        @Test
        void testSelectBatchIds() {
            List<Integer> ids = new ArrayList<>();
            ids.add(1);
            ids.add(2);
            ids.add(3);
            List<User> users = userMapper.selectBatchIds(ids);
            System.out.println(users);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Mybatis-Plus 日志:

    ==>  Preparing: SELECT id,name,age,email FROM tbl_user WHERE id IN ( ? , ? , ? )
    ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
    <==    Columns: id, name, age, email
    <==        Row: 1, Pauline Cole, 20, paulic59@icloud.com
    <==        Row: 2, Tao Chi Yuen, 17, chiyuentao@icloud.com
    <==        Row: 3, Xu Lan, 23, xul@hotmail.com
    <==      Total: 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2. 按多个 id 删除

    使用 deleteBatchIds() 方法实现,将一个 List 作为参数传入,里面存放着多个 id

    测试方法:

        @Test
        void testUpdateBatchIds() {
            List<Integer> ids = new ArrayList<>();
            ids.add(1);
            ids.add(2);
            ids.add(114514);	// 不存在此 id
            int ret = userMapper.deleteBatchIds(ids);
            System.out.println(ret);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Mybatis-Plus 日志:

    ==>  Preparing: DELETE FROM tbl_user WHERE id IN ( ? , ? , ? )
    ==> Parameters: 1(Integer), 2(Integer), 114514(Integer)
    <==    Updates: 2
    
    • 1
    • 2
    • 3

    三、逻辑删除

    逻辑删除指只对需要删除的数据打上已被删除的标记,而不真正删除库中的相关数据

    做法如下:

    1. 在表中设置标记字段

    例如下脚本建立表:

    DROP TABLE IF EXISTS `tbl_user`;
    CREATE TABLE `tbl_user`  (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `name` varchar(30) COMMENT  '姓名',
      `age` int COMMENT  '年龄',
      `email` varchar(50) COMMENT  '邮箱',
      `deleted` int DEFAULT 0 COMMENT '逻辑删除标记,默认为 0 表示未被删除',
      PRIMARY KEY (`id`)
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 实体类中注解 @TableLogic

    @TableLogic 注解中有两个属性,value 为默认值,表示未删除,delval 为表示已删除的值

    @Data
    @TableName("tbl_user")
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String name;
        private Integer age;
        private String email;
        @TableLogic(value = "0", delval = "1")
        private Integer deleted;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. 效果查看

    此时执行的任何操作都会加上 deleted = 0 的条件对数据进行过滤

    尝试查询所有行,测试类如下:

    @SpringBootTest
    public class MybatisPlusTest {
        @Autowired
        UserMapper userMapper;
        @Test
        void testSelectAll() {
            List<User> users = userMapper.selectList(null);
            System.out.println(users);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Mybatis-Plus 日志:

    ==>  Preparing: SELECT id,name,age,email,deleted FROM tbl_user WHERE deleted=0
    ==> Parameters: 
    <==    Columns: id, name, age, email, deleted
    <==        Row: 1, Arthur Bennett, 22, bennettart@yahoo.com, 0
    <==        Row: 2, Valerie Grant, 24, gravalerie@yahoo.com, 0
    <==        Row: 3, Thelma Powell, 19, powellthel@icloud.com, 0
    <==      Total: 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以看出 sql 语句后跟了 WHERE deleted=0 的条件

    再尝试按 id 删除操作,测试类如下:

    @SpringBootTest
    public class MybatisPlusTest  {
        @Autowired
        UserMapper userMapper;
        @Test
        void testDeleteById() {
            long id = 2;
            int ret = userMapper.deleteById(id);
            System.out.println(ret);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Mybatis-Plus 日志:

    ==>  Preparing: UPDATE tbl_user SET deleted=1 WHERE id=? AND deleted=0
    ==> Parameters: 2(Long)
    <==    Updates: 1
    
    • 1
    • 2
    • 3

    发现此时执行的是 UPDATE 操作而不是 DELETE 操作,只将 deleted 标记值从 0 改为 1 而没有删除任何数据

  • 相关阅读:
    C++_类和对象
    华为机试真题实战应用【赛题代码篇】-玩牌高手 (附Java、Python和C++代码)
    vue3项目,vite+vue3+ts+pinia(10)-elementplus布局
    ArcGIS土地利用程度综合指数分析
    Java面试-轻松搞定Java面试集合相关题目
    Redis 集群
    Centos下使用containerd管理容器:5分钟从docker转型到containerd
    微软Edge浏览器全解析
    aardio 调用 vs 编写的dll (stdcall方式) (dll又调用另一个dll)
    基于Unity3D开发的3D小游戏牧师与魔鬼
  • 原文地址:https://blog.csdn.net/Cey_Tao/article/details/126917735