简介
说明
本文介绍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(推荐) } } }
性能分析
性能损耗可以忽略不计。
请先
!