一、公共字段自动填充
需求:好多表公共的字段,赋值逻辑也相同,不用每次为其赋值,‘拦截器’统一赋值。
1. 在新增数据时,需要设置创建时间、创建人、修改时间、修改人等字段,在编辑数据时需要设置修改时间、修改人等字段。这些字段属于公共字段,也就是在我们的系统中很多表中都会有这些字段,如下:
而针对于这些字段,我们的赋值方式为:
A. 在新增数据时, 将createTime、updateTime 设置为当前时间, createUser、updateUser设置为当前登录用户ID。
B. 在更新数据时, 将updateTime 设置为当前时间, updateUser设置为当前登录用户ID。
2. 我们使用Mybatis Plus提供的公共字段自动填充功能。
2.1 实现步骤:
-
- 在实体类的属性上加入@TableField注解,指定自动填充的策略。
-
- 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。
2.2 代码实现
1). 实体类的属性上加入@TableField注解,指定自动填充的策略。
抽取公共基础实体类,在公共字段属性上, 加上注解, 指定填充策略 @TableField(fill=insert/update)
@Data
public class BaseEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 搜索值*/@JsonIgnore@TableField(exist = false)private String searchValue;/*** 创建者*/@TableField(fill = FieldFill.INSERT)private String createBy;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createTime;/*** 更新者*/@TableField(fill = FieldFill.INSERT_UPDATE)private String updateBy;/*** 更新时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;/*** 请求参数*/@JsonInclude(JsonInclude.Include.NON_EMPTY)@TableField(exist = false)private Map<String, Object> params = new HashMap<>();}
FieldFill.INSERT: 插入时填充该属性值FieldFill.INSERT_UPDATE: 插入/更新时填充该属性值
2). 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。
com.ltkj.framework.handler;
/*** 自定义元数据对象处理器* 用于insert或update sql语句时 自动填充公共字段值*/
@Slf4j
public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("公共字段自动填充[insert]...param: {}", metaObject);try {if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();Date current = ObjectUtil.isNotNull(baseEntity.getCreateTime())? baseEntity.getCreateTime() : new Date();baseEntity.setCreateTime(current);baseEntity.setUpdateTime(current);String username = StringUtils.isNotBlank(baseEntity.getCreateBy())? baseEntity.getCreateBy() : getLoginUsername();// 当前已登录 且 创建人为空 则填充baseEntity.setCreateBy(username);// 当前已登录 且 更新人为空 则填充baseEntity.setUpdateBy(username);}} catch (Exception e) {throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);}}@Overridepublic void updateFill(MetaObject metaObject) {log.info("公共字段自动填充[update]...param: {}", metaObject);try {if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();Date current = new Date();// 更新时间填充(不管为不为空)baseEntity.setUpdateTime(current);String username = getLoginUsername();// 当前已登录 更新人填充(不管为不为空)if (StringUtils.isNotBlank(username)) {baseEntity.setUpdateBy(username);}}} catch (Exception e) {throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);}}/*** 获取登录用户名*/private String getLoginUsername() {LoginUser loginUser;try {loginUser = LoginHelper.getLoginUser();} catch (Exception e) {log.warn("自动注入警告 => 用户未登录");return null;}return loginUser.getUsername();}}
然后,我们启动项目,在员工管理模块中,测试增加/更新员工信息功能,然后通过debug 或者 直接查询数据库数据变更的形式,看看我们在新增/修改数据时,这些公共字段数据是否能够完成自动填充。
测试可以