简介
说明
本文介绍MybatisPlus的自动填充的用法。
官网网址
使用场景
在数据入库的时候,不管新增或者修改数据,都要手动来设置添加时间和修改时间。每个插入都需要设置,而且数据库还设置不能为空,就很烦恼。
虽然可以在数据库设置默认值,但若没有数据库表修改权限,那就从技术上来解决这个问题吧。(如果有数据库表修改权限,可直接设置相应字段属性)。
失效的情况
- 使用自定义sql(Mapper的方法上边用@Update()等编写的语句)
- 解决方法:在自定义sql对应的方法里,多传一个时间参数。
- remove()等删除方法
- 解决方法1:用新版本的MyBatis-Plus。(自测成功的版本:mybatis-plus-boot-starter:3.4.1、3.4.2、3.5.1)
- 解决方法2:使用removeById()、deleteById()、手动调用set语句等。见:官方网站
- 解决方法3:写一个全局的MyBatis拦截器,填充相应字段。
entity
在实体类字段上,通过注解方式设置需要在执行什么操作填充,一共有三种:新增、更新、删除操作。
当然
@Data
@TableName("t_user")
public class User {
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 插入与更新都写此字段。
* 若使用FieldFill.UPDATE,则只更新时写此字段。
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
handler(推荐的写法)
如果有些数据库的表没有创建时间和修改时间字段,如果执行这些操作有点浪费,可以判断是否有setter。
在3.3.2及之后的版本中,已经有了这样的功能,而之前的版本需要手动判断。
mybatis-plus3.3.2及之后
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
@Slf4j
@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
/**
* 自动填充插件
*/
@Bean
public MetaObjectHandler metaObjectHandler() {
return new MybatisPlusAutoFillConfig();
}
}
package com.example.demo.config.mybatisplus.inner;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import java.time.LocalDateTime;
@Slf4j
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
/**
* 新增时填充
*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("新增:自动填充createTime:" + LocalDateTime.now());
// 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
// 更新时间最好也填充一下
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
// 或者(起始版本 3.3.3(推荐))
// this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class);
// 或者(3.3.0 该方法有bug)
// this.fillStrategy(metaObject, "createTime", LocalDateTime.now());
// 或者(不推荐)
// setFieldValByName("createTime", LocalDateTime.now(), metaObject);
// setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
/**
* 修改时填充
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("更新:自动填充updateTime:" + LocalDateTime.now());
// 起始版本 3.3.0(推荐使用)
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
// 或者(起始版本 3.3.3(推荐))
// this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class);
// 或者(3.3.0 该方法有bug)
// this.fillStrategy(metaObject, "updateTime", LocalDateTime.now());
// 或者(不推荐)
// setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
配置文件另一种写法
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
private static final Logger logger= LoggerFactory.getLogger(MybatisPlusAutoInjectConfig.class);
// 新增时填充
@Override
public void insertFill(MetaObject metaObject) {
logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
boolean hasCreateTimeSetter = metaObject.hasSetter("createTime");
Object createTime = getFieldValByName("createTime", metaObject);
if (hasCreateTimeSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
}
boolean hasupdateTimeSetter = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if (hasupdateTimeSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
// 修改时填充
@Override
public void updateFill(MetaObject metaObject) {
logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
boolean hasSetter = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if (hasSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
}
mybatis-plus3.3.2之前
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
private static final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);
//自动填充插件
@Bean
public MetaObjectHandler metaObjectHandler() {
return new MybatisPlusAutoFillConfig();
}
public static class MybatisPlusAutoFillConfig implements MetaObjectHandler {
// 新增时填充
@Override
public void insertFill(MetaObject metaObject) {
logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
setFieldValByName("createTime", LocalDateTime.now(), metaObject);
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
// 修改时填充
@Override
public void updateFill(MetaObject metaObject) {
logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
}
也可以这样写配置文件
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MybatisPlusAutoFillConfig implements MetaObjectHandler {
private static final Logger logger= LoggerFactory.getLogger(MybatisPlusAutoInjectConfig.class);
// 新增时填充
@Override
public void insertFill(MetaObject metaObject) {
logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
boolean hasCreateTimeSetter = metaObject.hasSetter("createTime");
Object createTime = getFieldValByName("createTime", metaObject);
if (hasCreateTimeSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setInsertFieldValByName("createTime", LocalDateTime.now(), metaObject);
}
boolean hasupdateTimeSetter = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if (hasupdateTimeSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
// 修改时填充
@Override
public void updateFill(MetaObject metaObject) {
logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
boolean hasSetter = metaObject.hasSetter("updateTime");
Object updateTime = getFieldValByName("updateTime", metaObject);
if (hasSetter) {
// 第一个参数对应实体属性名, 第二个参数需要填充的值
setUpdateFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
}
handler(不推荐的写法)
因为如果updateTime不是null,则不会更新updateTime,不适用于先查出数据修改后再写入的情况
package com.example.base.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
@Configuration
//@MapperScan("com.example.**.mapper")
public class MyBatisPlusConfig {
private static final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);
//自动填充插件
@Bean
public MetaObjectHandler metaObjectHandler() {
return new MybatisPlusAutoFillConfig();
}
public static class MybatisPlusAutoFillConfig implements MetaObjectHandler {
// 新增时填充
@Override
public void insertFill(MetaObject metaObject) {
logger.info("插入:自动填充createTime和updateTime:"+ LocalDateTime.now());
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
// 或者
// this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
// this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
}
// 修改时填充
@Override
public void updateFill(MetaObject metaObject) {
logger.info("更新:自动填充updateTime:" + LocalDateTime.now());
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
// 或者
// this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
}
}
}
性能分析
性能损耗可以忽略不计。

请先 !