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

1、主键id的生成

数据库表里一般都会有一个主键id,来做为这条数据的惟一标识。redis

常见的方式

  1. 数据库自动增加
    这种很常见了,能够作到全库惟一。由于id是自然排序的,对于涉及到排序的操做会很方便。算法

  2. UUID
    上面的自动增加,虽然简单,可是对于分表这样的操做来讲就比较麻烦。由于你在第二张插入数据的时候,须要拿到上一张表最后一个数据的id。
    UUID则不一样,每次都一个随机惟一的值,不过由于是随机,因此也就没有排序了。spring

  3. redis
    redis也能够用来生成id,利用redis的原子操做。好处是能够不依赖数据库,性能好,可是随之由于redis的引入,带来了必定的复杂度。数据库

mybatis-plus的方式

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

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

@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。分布式

2、mp实现自动填充

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

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);

    }

结果正确。

相关文章
相关标签/搜索