mybatisplus带的公共字段自动填充
通常,记录数据时会存在公共字段,为了方便插入,可以使用mybatisplus带的公共字段自动填充, 例如:记录创建信息和更新信息
@ApiModelProperty(value = "创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
private Date createTime;
@ApiModelProperty(value = "创建人id")
@TableField(value = "create_user_id", fill = FieldFill.INSERT)
private Long createUserId;
@ApiModelProperty(value = "创建人姓名")
@TableField(value = "create_user_name", fill = FieldFill.INSERT)
private String createUserName;
@ApiModelProperty(value = "修改时间")
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private Date updateTime;
@ApiModelProperty(value = "修改人id")
@TableField(value = "update_user_id", fill = FieldFill.UPDATE)
private Long updateUserId;
@ApiModelProperty(value = "修改人姓名")
@TableField(value = "update_user_name", fill = FieldFill.UPDATE)
private String updateUserName;
存在这么一种情况,当我没有赋值这个数据的时候自动插入,如果赋值了就插入自己的值。
自动填充步骤:
1、在实体类的属性上加入@TableField注解,指定自动填充策略
2、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,需要实现MetaObjectHandler接口
3、 使用:
fill = FieldFill.INSERT
新增
fill = FieldFill.INSERT_UPDATE
新增和修改
fill = FieldFill.UPDATE
修改
CustomMetaObjectHandler.java
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
//【注意】属性名称,不是字段名称
if (Objects.isNull(curUserId) && metaObject.hasGetter("createUserId") && Objects.isNull(metaObject.getValue("createUserId"))) {
this.setFieldValByName("createUserId", 1L, metaObject);
}
Object createUserId = this.getFieldValByName("createUserId", metaObject);
//对于手动赋值的数据,不再自动赋值
if(Objects.nonNull(createUserId))
{
//System.out.println(createUserId);
}
else if (Objects.nonNull(curUserId)) {
this.setFieldValByName("createUserId", curUserId, metaObject);
}
Object createUserName = this.getFieldValByName("createUserName", metaObject);
if(createUserName instanceof String && StringUtils.isNotBlank((String)createUserName))
{
//System.out.println(createUserName);
}
else
{
this.setFieldValByName("createUserName", CommonUtil.getCurrentUserName(), metaObject);
}
Object createTime = this.getFieldValByName("createTime", metaObject);
if(createTime != null)
{
// System.out.println(createTime);
}
else
{
this.setFieldValByName("createTime", CommonUtil.getCurrentDate(), metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
//如果有需要,同上
this.setFieldValByName("updateTime", CommonUtil.getCurrentDate(), metaObject);
this.setFieldValByName("updateUserId", CommonUtil.getCurrentUserId(), metaObject);
this.setFieldValByName("updateUserName", CommonUtil.getCurrentUserName(), metaObject);
}
}
这里,如果存在项目中重写SqlSessionFactory,需要添加配置:
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("mybatisPlusInterceptor") MybatisPlusInterceptor mybatisPlusInterceptor,
CustomMetaObjectHandler customMetaObjectHandler
) throws Exception {
MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
sessionFactoryBean.setDataSource(buildDataSource());
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/**/*.xml"));
sessionFactoryBean.setPlugins(mybatisPlusInterceptor);
GlobalConfig globalConfig = new GlobalConfig();
//这里!!
globalConfig.setMetaObjectHandler(customMetaObjectHandler);
globalConfig.setSqlInjector(new MyInjector());
sessionFactoryBean.setGlobalConfig(globalConfig);
return sessionFactoryBean.getObject();
}
【补充】
MybatisPlus 字段更新策略 FieldStrategy使用
Mybatis-plus默认的更新策略是NOT_NULL:非NULL,也就是传数据为NULL时不更新数据库中该字段的值。
Mybatis-plus通过updateById()更新数据,当传值为NULL且需要对该字段更新为NULL时,需要对FieldStrategy 策略进行调整。
public enum FieldStrategy {
//忽略空值判断,实体对象的字段是什么值就用什么值更新,支持null值更新操作
IGNORED,
//非NULL判断
NOT_NULL,
//非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
NOT_EMPTY,
//默认
DEFAULT,
//不加入 SQL
NEVER
}
第一种:在配置文件中全局配置
//默认都是DEFAULT,也就是NOT_NULL
mybatis-plus.global-config.db-config.update-strategy=not_null
mybatis-plus.global-config.db-config.insert-strategy=not_null
mybatis-plus.global-config.db-config.where-strategy=not_null
第二种:单个字段
@ApiModelProperty(value = "创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
private Date createTime;
实战:
@Data
@TableName("rewrite_sql")
public class RewriteSqlDO implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
private Integer id;
private String stuName;
private Integer age;
@TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
// @TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_NULL)
// @TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NOT_EMPTY)
// @TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NEVER)
private Date createTime;
}
初始值:
@Test
void test4() {
//测试策略
RewriteSqlDO rewriteSqlDO = new RewriteSqlDO();
rewriteSqlDO.setId(1);
rewriteSqlDO.setAge(2);
rewriteSqlDO.setStuName(String.valueOf(2));
// rewriteSqlDO.setCreateTime(TimeUtil.sdfStrToDate("2023-12-31", "yyyy-MM-dd"));
rewriteSqlMapper.updateById(rewriteSqlDO);
}
1、FieldStrategy.IGNORED
结果:忽略字段值的空值判断,无论实体对象的字段值是否为空,都会进行更新操作。
【注意:】如果传的值为空,则更新为NULL。
2、FieldStrategy.NOT_NULL
结果:进行NULL值判断,如果为NULL,则不更新对应的字段。
3、FieldStrategy.NOT_EMPTY
结果:字符串进行空值判断,只有非空字符串的字段才会参处理与数据。
3、FieldStrategy.NOT_EMPTY
结果:字符串进行空值判断,只有非空字符串的字段才会参处理与数据。
4、FieldStrategy.NEVER
结果:忽略字段值的空值判断,不管标识的字段是否有值,都不会进行更新操作。
@Test
void test4() {
RewriteSqlDO rewriteSqlDO = new RewriteSqlDO();
rewriteSqlDO.setId(1);
rewriteSqlDO.setAge(2);
rewriteSqlDO.setStuName(String.valueOf(2));
rewriteSqlDO.setCreateTime(TimeUtil.sdfStrToDate("2023-12-31", "yyyy-MM-dd"));
rewriteSqlMapper.updateById(rewriteSqlDO);
}
这里引出了一个问题: update_time字段未自动更新
当使用selectById()时,没有进行自动更新create_time。原因就是:默认的是NOT_NULL,当赋值的时候没有重新赋值这个值,那么就不会更新。
需要注意。解决方案如上,更换其他策略。
- 字段 mybatis-plus mybatis plusmybatis-plus mybatis plus字段 字段mybatis-plus mybatis plus 字段mybatis-plus mybatis blob 最大值 字段mybatis-plus mybatis 字段mybatis-plus mybatis update 字段mybatis-plus threadlocal mybatis mybatis-plus mybatis-plus mybatis plus 字段mybatis-plus mybatis部分 mybatis-plus springboot mybatis mapper