目录
一.前言:
在我们平时开发中, 设计表的时候会有公共字段,比如PDManer(数据库设计软件) 我们导入数据域, 会有一些公共字段,这些字段在我们平时业务交互的时候是需要维护的,在我们添加或更新的时候会赋值,今天看一下我们如何自动填充公共字段并保存。
例如:
mubatis-plus依赖
注:我的配置是基于MyBatis-plus 3.3.1的版本
<!--MyBatis-plus starter-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.3.1</version>
</dependency>
二、解决方法
2.1原始代码(手动set公共字段)
手动set公共值
添加:
public boolean saveTest(Test test) {
test.setCreatedTime(new Date());
test.setCreatedBy(RequestContext.getLoginUserId());
return super.save(test);
}
更新:
public boolean updateTest(Test test) {
test.updateBy(RequestContext.getLoginUserId());
test.updateTime(new Date());
return super.updateById(test);
}
手动是很麻烦的, 每次个添加接口和更新接口都需要set默认值
2.2方案一:注解自动填充
- 实体类中(pojo类)需要自动填充的属性通过@TableField的fill属性进行标注
- FieldFill为字段填充策略枚举类,定义了DEFAULT(默认不处理)、INSERT(插入时填充字段)、UPDATE(更新时填充字段)、INSERT_UPDATE(插入和更新时填充字段)等4种填充策略
注释: @TableField注解:
1、 主要用来解决实体类的字段名与数据库中的字段名不匹配的问题(数据库user_addr,字段useraddr未驼峰)
2、 实体类中的属性字段在表中不存在的问题
3.表示自动填充字段一般用于字段名
属性 | 类型 | 必须指定 | 默认值 | 描述 |
value | String | 否 | "" | 数据库字段名 |
exist | boolean | 否 | true | 是否为数据库表字段 |
condition | String | 否 | "" | 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s} ,参考(opens new window) |
update | String | 否 | "" | 字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性) |
insertStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_NULL insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>) |
updateStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:IGNORED update table_a set column=#{columnProperty} |
whereStrategy | Enum | 否 | FieldStrategy.DEFAULT | 举例:NOT_EMPTYwhere <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> |
fill | Enum | 否 | FieldFill.DEFAULT | 字段自动填充策略 |
select | boolean | 否 | true | 是否进行 select 查询 |
keepGlobalFormat | boolean | 否 | false | 是否保持使用全局的 format 进行处理 |
jdbcType | JdbcType | 否 | JdbcType.UNDEFINED | JDBC 类型 (该默认值不代表会按照该值生效) |
typeHandler | Class<? extends TypeHandler> | 否 | UnknownTypeHandler.class | 类型处理器 (该默认值不代表会按照该值生效) |
numericScale | String | 否 | "" | 指定小数点后保留的位数 |
代码:
@ApiModelProperty(value = "创建人")
@TableField(fill = FieldFill.INSERT)
private Long createdBy;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date createdTime;
@ApiModelProperty(value = "更新人")
@TableField(fill = FieldFill.INSERT)
private Long updatedBy;
@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT)
private Date updatedTime;
2.2方案二: 自己编写自定义填充
这里是比较活泛的
/**
* 自定义sql字段填充器,自动填充创建修改相关字段
*/
public class CustomMetaObjectHandler implements MetaObjectHandler {
private static final String CREATE_USER = "createUser";
private static final String INSERT_TIME = "insertTime";
private static final String UPDATE_USER = "updateUser";
private static final String UPDATE_TIME = "updateTime";
@Override
public void insertFill(MetaObject metaObject) {
//为空则设置createUser
Object createUser = metaObject.getValue(CREATE_USER);
if(ObjectUtil.isNull(createUser)) {
setFieldValByName(CREATE_USER, this.getUserUniqueId(), metaObject);
}
//为空则设置insertTime
Object insertTime = metaObject.getValue(INSERT_TIME);
if(ObjectUtil.isNull(insertTime)) {
setFieldValByName(INSERT_TIME, new Date(), metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
setFieldValByName(UPDATE_TIME, new Date(), metaObject);
setFieldValByName(UPDATE_USER, this.getUserUniqueId(), metaObject);
}
/**
* 获取用户唯一id
*/
private Long getUserUniqueId() {
return -1L;
/*try {
SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUserWithoutException();
if(ObjectUtil.isNotNull(sysLoginUser)) {
return sysLoginUser.getId();
} else {
return -1L;
}
} catch (Exception e) {
//如果获取不到就返回-1
return -1L;
}*/
}
}