• 【mybatis-plus】主键id生成、字段自动填充


    一、主键id的生成

    数据库表里通常都会有一个主键id,来作为这条数据的唯一标识。

    常见的方式

    1. 数据库自动增长
      这种很常见了,可以做到全库唯一。因为id是天然排序的,对于涉及到排序的操作会很方便。

    2. UUID
      上面的自动增长,虽然简单,但是对于分表这样的操作来说就比较麻烦。因为你在第二张插入数据的时候,需要拿到上一张表最后一个数据的id。
      UUID则不同,每次都一个随机唯一的值,不过因为是随机,所以也就没有排序了。

    3. redis
      redis也可以用来生成id,利用redis的原子操作。好处是可以不依赖数据库,性能好,但是随之因为redis的引入,带来了一定的复杂度。

    mybatis-plus的方式

    其实在之前使用mp进行新增数据的时候,我并没有进行对应的配置,默认就会带有主键id。

    对其配置也很简单,在主键上加注解,@TableId(type = IdType.ID_WORKER)

    @Data
    public class User {
        @TableId(type = IdType.ID_WORKER)
        private Long id;
        private String name;
        private Integer age;
        private String email;
    
        @TableField(fill = FieldFill.INSERT)
        private Date createTime;
        @TableField(fill = FieldFill.INSERT_UPDATE) // 新增的时候update也有值
        private Date updateTime;
    }
    

    在idea编辑器里,可以按住ctrl+鼠标左击,看到IdType的几个枚举值。

    • AUTO:就是利用数据库自增了
    • NONE:未设置,需要手动设置值
    • INPUT: 需要手动设置值
    • UUID:生成UUID类型的主键id
    • ID_WORKER:生成19位的值,数字类型
    • ID_WORKer_STR:生成19位的值,字符串类型

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

    二、mp实现自动填充

    在操作数据库的时候还有一种常见操作,就是一些字段的填充,比如常见的create_time、update_time等,填充方式都是相同的。
    那么除了每次的手动填充,还可以自动填充。而在MP里设置自动填充只要2步即可:

    1.添加注解

    @TableField(fill = FieldFill.INSERT)@TableField(fill = FieldFill.INSERT_UPDATE)

    @Data
    public class User {
        @TableId(type = IdType.ID_WORKER)
        private Long id;
        private String name;
        private Integer age;
        private String email;
    
        @TableField(fill = FieldFill.INSERT)        // 新增的时候填充数据
        private Date createTime;
        @TableField(fill = FieldFill.INSERT_UPDATE) // 新增或修改的时候填充数据
        private Date updateTime;
    }
    

    2.自定义实现类 MyMetaObjectHandler

    这里需要我们自己写一个实现类

    @Component //此注解表示 将其交给spring去管理
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            this.setFieldValByName("createTime", new Date(), metaObject);
            this.setFieldValByName("updateTime", new Date(), metaObject);
        }
    
    
        @Override
        public void updateFill(MetaObject metaObject) {
            this.setFieldValByName("updateTime", new Date(), metaObject);
        }
    }
    

    对了,要在数据库表里增加对应的字段create_timeupdate_time。添加后可以试一下了,先来新增一条测试数据:

    //    新增
        @Test
        void addUser() {
            User user = new User();
            user.setName("老王");
            user.setAge(66);
            user.setEmail("laowang@123.com");
            userMapper.insert(user);
        }
    

    执行成功后查看数据库表:


    新增的时候,2个字段都填充了时间。

    那现在只做更新操作的时候,只会去更新update_time。

    //    修改
        @Test
        void updateUser() {
            User user = new User();
            user.setId(1342322873243996161L);
            user.setName("老王修改后");
            userMapper.updateById(user);
    
        }
    


    结果正确。

  • 相关阅读:
    E
    C. Connect Three(构造)
    判断矩形相交的方法
    字典树&&01字典树专题&&对字典树的理解
    J
    kmp专题
    Python 字典 popitem() 方法
    Python 字典 pop() 方法
    Python 字典(Dictionary) values()方法
    Python 字典(Dictionary) update()方法
  • 原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/14187096.html
Copyright © 2020-2023  润新知