主键策略(ID自动生成)
以下是MyBatis-Plus中常见的几种主键生成策略及其对应的枚举值(3.3.0之前的版本):
主键生成策略 | 枚举值 |
---|---|
数据库自增 | IdType.AUTO |
用户输入 | IdType.INPUT |
分布式全局唯一ID | IdType.ID_WORKER |
分布式全局唯一ID(字符串类型) | IdType.ID_WORKER_STR |
UUID | IdType.UUID |
雪花算法全局唯一ID | IdType.SNOWFLAKE |
雪花算法全局唯一ID(字符串类型) | IdType.SNOWFLAKE_STR |
3.3.0之后的版本:
值 | 描述 |
---|---|
AUTO | 数据库自增,适用于MySQL、SQL Server等数据库 |
INPUT | 手动输入,适用于全局唯一ID的情况,自定义 |
ASSIGN_UUID | 32位UUID字符串 |
ASSIGN_ID | 分布式全局唯一ID,雪花算法生成 |
NONE | 无状态,可以通过全局唯一ID进行填充 |
public enum IdType {
AUTO(0), //数据库自增长,mysql的自增长主键
NONE(1), //未设置
INPUT(2), //自定义设置
ASSIGN_ID(3), //分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),
//使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID(4); //分配 UUID,主键类型为 String(since 3.3.0),
//使用接口IdentifierGenerator的方法nextUUID(默认default 方法)
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
配置文件中全局配置:
#配置数据源
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/book_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123
driver-class-name: com.mysql.cj.jdbc.Driver
#mybatisplus配置
mybatis-plus:
global-config:
db-config:
#配置id自增长,ID自动生成策略
id-type: auto
configuration:
#配置mybatisplus日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:/mapper/*.mapper.xml #xml文件的位置(resources下的mapper文件夹)
注: 实体类@TableId注解的type属性会覆盖全局属性,优先以各实体类的配置为主,未配置的则全局配置生效
公共字段自动填充的使用
- 实体类公共字段 添加@TableField注解,配置fill属性:
值 | 描述 |
---|---|
INSERT | 插入时填充 |
UPDATE | 更新时填充 |
INSERT_UPDATE | 插入和更新时填充 |
DEFAULT | 默认不填充 |
- 实现MetaObjectHandler接口,重写insertFill和updateFill方法,并注册为Bean
@Slf4j
@Component
public class MybatisplusHandler implements MetaObjectHandler {
// 插入时的填充策略
/**
* 数据创建时间的属性名
*/
public static final String FIELD_CREATE_TIME = "createTime";
/**
* 数据最后修改时间的属性名
*/
public static final String FIELD_UPDATE_TIME = "updateTime";
public static final String FIELD_CREATE_USER = "createUser";
public static final String FIELD_UPDATE_USER = "updateUser";
@Override
public void insertFill(MetaObject metaObject) {
LocalDateTime now = LocalDateTime.now();
Long id = BaseContext.getCurrentId();
log.info("开始执行插入时的自动填充");
log.info("metaob{}",metaObject.toString());
this.strictInsertFill(metaObject,FIELD_CREATE_USER, Long.class, id);
this.strictUpdateFill(metaObject,FIELD_UPDATE_USER, Long.class, id);
this.strictInsertFill(metaObject,FIELD_CREATE_TIME, LocalDateTime.class, now);
this.strictUpdateFill(metaObject,FIELD_UPDATE_TIME, LocalDateTime.class, now);
}
@Override
public void updateFill(MetaObject metaObject) {
LocalDateTime now = LocalDateTime.now();
Long id = BaseContext.getCurrentId();
this.strictUpdateFill(metaObject,FIELD_UPDATE_TIME, LocalDateTime.class, now);
this.strictUpdateFill(metaObject,FIELD_UPDATE_USER, Long.class, id);
}
}
注意事项:在使用公共字段自动填充和id自动生成时,自定义的insert和update的Mapper方法不得进行判空,否则自动填充不生效。这是由于mybatisplus的底层是先执行自定义的SQL,后填充。此时公共自段未传入,如果进行判空的话,mybatis就不会拼接该字段,后面填充时也不会插入该字段。
<insert id="insert" parameterType="com.sky.entity.Employee">
INSERT INTO employee
<trim prefix="(" suffix=")" suffixOverrides=",">
id,
<if test="name != null">name,</if>
<if test="username != null">username,</if>
<if test="password != null">password,</if>
<if test="phone != null">phone,</if>
<if test="sex != null">sex,</if>
<if test="idNumber != null">id_number,</if>
<if test="status != null">status,</if>
create_time,
update_time,
create_user,
update_user
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
#{id,jdbcType=BIGINT},
<if test="name != null">#{name,jdbcType=VARCHAR},</if>
<if test="username != null">#{username,jdbcType=VARCHAR},</if>
<if test="password != null">#{password,jdbcType=VARCHAR},</if>
<if test="phone != null">#{phone,jdbcType=VARCHAR},</if>
<if test="sex != null">#{sex,jdbcType=VARCHAR},</if>
<if test="idNumber != null">#{idNumber,jdbcType=VARCHAR},</if>
<if test="status != null">#{status,jdbcType=INTEGER},</if>
#{createTime,jdbcType=TIMESTAMP},
#{updateTime,jdbcType=TIMESTAMP},
#{createUser,jdbcType=BIGINT},
#{updateUser,jdbcType=BIGINT}
</trim>
</insert>```