开发中,我们常常在数据库的大部分表中喜欢预留一些通用字段,比如插入时间、更新时间、创建人等等,有些字段可以通过数据库表设置列的默认值,有些业务范围的默认值就必须由java来生成,mybaits-plus框架在使用过程,设置了这样一个填充功能,可以发生在DDL操作中。
- 所有orm实体类,抽离一个父类,包含了通用的字段,并使用@TableField注解fill属性来设置填充的DDL时机
@Data
public abstract class DataEntity implements Serializable {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 创建者
*/
@TableField(fill = FieldFill.INSERT)
private Long createUser;
/**
* 插入时间
*/
@TableField(fill = FieldFill.INSERT)
private Date insertTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
- 注册mybatis-plus填充handler处理类
@Component
public class MybatisFillHandler implements MetaObjectHandler {
private final static Log log = LogFactory.getLog("mybatis-plus-fillHandler");
@Override
public void insertFill(MetaObject metaObject) {
User user = UserUtil.getAdminUser();
if (Objects.isNull(user)) {
user = UserUtil.getApiUser();
}
if (Objects.nonNull(user)) {
log.info("开始填充创建者CreateUser");
this.setInsertFieldValByName("createUser", user.getId(), metaObject);
}
log.info("开始填充插入时间InsertTime");
this.setInsertFieldValByName("insertTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("开始填充更新时间UpdateTime");
this.setUpdateFieldValByName("updateTime", new Date(), metaObject);
}
}
- 业务实体类集成该父类
@Data
public class Activity extends DataEntity {
private static final long serialVersionUID = 1L;
private String name;
private String url;
private Long orders;
private String enable;
private Long thumb;
private String type;
}
- 如果是不同业务有不同的抽离字段,需要用到多个实体类父类,那么我们可以在handler中,使用MetaObject对象来进行判断,例如insertFill(MetaObject metaObject)
@Override
public void insertFill(MetaObject metaObject) {
String[] setterNames = metaObject.getSetterNames();
HashSet<String> setterNameSet = new HashSet<>(Arrays.asList(setterNames));
if(setterNameSet.contains("insertTime")){
//... to do something
}
if(setterNameSet.contains("createUser")){
//... to do something
}
}