MybatisPlus自动填充公共字段及特定类型属性设置默认值
程序员文章站
2022-03-10 18:35:26
前言MybatisPlus是一个 MyBatis的增强工具,集成了mybatis和hibernate各自的优点,所以很受一些企业的喜爱。目前我们公司就在使用,确实特别好用。本文重点介绍自动填充公共字段及特定字段类型设置默认值的方法。之前写过一篇关于JPA和mybatis自动填充的文章,有兴趣的小伙伴可以进行查看:链接属性填充首先MP为我们提供了元数据处理接口MetaObjectHandler,里面提供了很多默认填充实现方法供我们使用。其中insertFill和updateFill是新建和更新的填充方...
前言
MybatisPlus是一个 MyBatis的增强工具,集成了mybatis和hibernate各自的优点,所以很受一些企业的喜爱。目前我们公司就在使用,确实特别好用。本文重点介绍自动填充公共字段及特定字段类型设置默认值的方法。
之前写过一篇关于JPA和mybatis自动填充的文章,有兴趣的小伙伴可以进行查看:链接
属性填充
首先MP为我们提供了元数据处理接口MetaObjectHandler,里面提供了很多默认填充实现方法供我们使用。其中insertFill和updateFill是新建和更新的填充方法,默认没有实现,需要我们自己实现。
其实现原理和mybatis的一样,在MybatisPlusAutoConfiguration自动配置类里面会根据MetaObjectHandler.class找到相应的Bean,然后配置到全局配置的元对象字段填充控制器属性上。源码如下:
获取Bean并设置
自定义属性填充器
直接上代码,注意点如下:
- 需要将填充器注入到spring容器,此处直接加@Component。
- 填充的fieldName是实体类的属性名,而不是对应表的字段名。
/**
3. 元对象字段填充控制器
4. 自定义填充公共字段 ,即没有传的字段自动填充
5. 6. @author gourd.hu
**/
@Component
public class FillMetaObjectHandler implements MetaObjectHandler {
/**
* 新增填充
*
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
JwtToken currentUser = JwtUtil.getCurrentUser();
// 创建填充
fillCreateMeta(metaObject, currentUser);
// 更新填充
fillUpdateMeta(metaObject, currentUser);
}
/**
* 更新填充
*
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
JwtToken currentUser = JwtUtil.getCurrentUser();
fillUpdateMeta(metaObject,currentUser);
}
/**
* 填充创建数据
* @param metaObject
* @param currentUser
*/
private void fillCreateMeta(MetaObject metaObject, JwtToken currentUser) {
Long userId = currentUser == null ? 1L: currentUser.getUserId();
String userName = currentUser == null ? "007": currentUser.getUserName();
if (metaObject.hasGetter(RbacConstant.META_CREATED_BY) && metaObject.hasGetter(RbacConstant.META_CREATED_TIME)) {
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_BY,Long.class, userId);
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_TIME,LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject,RbacConstant.META_DELETED,Boolean.class,Boolean.FALSE);
this.strictInsertFill(metaObject,RbacConstant.META_VERSION,Integer.class,1);
}
if(metaObject.hasGetter(RbacConstant.META_CREATED_NAME)){
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_NAME,String.class, userName);
}
}
/**
* 填充更新数据
* @param metaObject
* @param currentUser
*/
private void fillUpdateMeta(MetaObject metaObject, JwtToken currentUser) {
Long userId = currentUser == null ? 1L: currentUser.getUserId();
String userName = currentUser == null ? "007": currentUser.getUserName();
if (metaObject.hasGetter(RbacConstant.META_UPDATED_BY) && metaObject.hasGetter(RbacConstant.META_UPDATED_TIME)) {
// fillStrategy方法会判断属性是否有值,如果有值就不会覆盖,所以调整为setFieldValByName方法
this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_BY,Long.class, userId);
this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_TIME,LocalDateTime.class, LocalDateTime.now());
}
if(metaObject.hasGetter(RbacConstant.META_UPDATED_NAME)){
this.strictUpdateFill(metaObject,RbacConstant.META_UPDATED_NAME,String.class, userName);
}
}
}
这样就可以实现属性的自动填充了。当然里面的填充逻辑,可以根据自己业务自定义调整。
特定类型属性设置默认值
有些时候,我们需要数据的一些字段不存储null值,我们可以通过给这些字段填充默认值实现。有三种方式:
- 数据库字段直接设置默认值,但如果代码中自定义sql插入还是可以填充null值。
- 实体属性设置默认值,如 private Integer count=0;但是这种情况在更新的时候,会存在误更新。
- 自定义填充器,创建填充时为特定类型设置默认值。
如下:
/**
* 填充创建数据
* @param metaObject
* @param currentUser
*/
private void fillCreateMeta(MetaObject metaObject, JwtToken currentUser) {
Long userId = currentUser == null ? 1L: currentUser.getUserId();
String userName = currentUser == null ? "007": currentUser.getUserName();
if (metaObject.hasGetter(RbacConstant.META_CREATED_BY) && metaObject.hasGetter(RbacConstant.META_CREATED_TIME)) {
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_BY,Long.class, userId);
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_TIME,LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject,RbacConstant.META_DELETED,Boolean.class,Boolean.FALSE);
this.strictInsertFill(metaObject,RbacConstant.META_VERSION,Integer.class,1);
}
if(metaObject.hasGetter(RbacConstant.META_CREATED_NAME)){
this.strictInsertFill(metaObject,RbacConstant.META_CREATED_NAME,String.class, userName);
}
// 插入数据,Integer默认设置0,String类型默认设置空字符串
List<TableFieldInfo> fieldList = this.findTableInfo(metaObject).getFieldList();
Object originalObject = metaObject.getOriginalObject();
for (TableFieldInfo fieldInfo : fieldList) {
if(Integer.class.equals(fieldInfo.getPropertyType())){
try {
Object o = fieldInfo.getField().get(originalObject);
if(o == null){
this.strictInsertFill(metaObject,fieldInfo.getProperty(), Integer.class,0);
}
} catch (IllegalAccessException e) {
log.error("Integer类型属性值填充异常");
}
}
if(String.class.equals(fieldInfo.getPropertyType())){
try {
Object o = fieldInfo.getField().get(originalObject);
if(o == null){
this.strictInsertFill(metaObject,fieldInfo.getProperty(), String.class,"");
}
} catch (IllegalAccessException e) {
log.error("String类型属性值填充异常");
}
}
}
}
这样就实现了特定类型属性设置默认值,如果你有更好的方式,欢迎评论告知。
本文地址:https://blog.csdn.net/HXNLYW/article/details/112600665
上一篇: Java基础语法题目练习
下一篇: Java专业人士必备的书籍和网站列表