MyBatis-Plus踩坑笔记
出于补充mb-plus 2.x版本文档编写不够详尽部分的目的编写本篇内容,作者水平有限,仅对类似问题提供思路。叠甲,过!
本篇介绍mb-plus提供的两个扩展功能的实践:公共字段自动填充和通用枚举自动注入,分别提供数据表公共字段(创建时间、创建人等)在行记录新增/更新时的自动填充功能,行记录中数据字典代码序列化(to json)时找到对应数据字典名称能力。使用扩展功能时应阅读2.x版本文档,结合阅读博客文章和3.x文档,以尽量避免踩坑。
jdk:jdk1.8.0
springboot:2.1.3
mybatis-plus:2.3.3
一、通用枚举扫描并自动关联注入
1. 创建枚举类,必须实现 IEnum 接口
public enum AgeEnum implements IEnum {
ONE(1, "一岁"),
TWO(2, "二岁");
private int value;
private String desc;
AgeEnum(final int value, final String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Serializable getValue() {
return this.value;
}
public String getDesc(){
return this.desc;
}
}
2. 在配置文件(e.g.application.yml)中配置扫描枚举的路径
mybatis-plus:
typeEnumsPackage: top.hanjiale.enums
3. 在实体类(entity)中改写需要带出数据字典名称(字典描述)的属性
@ApiModelProperty(value = "值班类型")
@TableField("duty_type")
private AgeEnum age;
注意,这里的age属性的类型不是Int也不是String,而是我们第一步创建的枚举类AgeEnum
4. 序列化时带出字典名称
这里介绍jackson,Fastjson官方文档较详细,仅列出
jackson
注意,这里需要数据库中存储的数据字典代码与枚举类的枚举类型名相同,在本例中,数据表内保存的文本可以是ONE、TWO,但不可以是数字1、2
若在AgeEnum的getDesc方法上标记@JsonValue:
@JsonValuepublic
String getDesc(){ return this.desc;}
则前端得到"age": "一岁"
若在枚举上标记@JsonFormat(shape= JsonFormat.Shape.OBJECT):
@JsonFormat(shape= JsonFormat.Shape.OBJECT)
public enum DutyTypeEnum implements IEnum {
……
}
则前端得到"age": {"value": "1","desc": "一岁"}
Fastjson
1.全局处理方式
FastJsonConfig config = new FastJsonConfig();
//设置WriteEnumUsingToString
config.setSerializerFeatures(SerializerFeature.WriteEnumUsingToString);
converter.setFastJsonConfig(config);
2.局部处理方式
@JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
private UserStatus status;
以上两种方式任选其一,然后在枚举中复写toString方法即可。
5.反序列化
当前端传入时,若值无法匹配枚举,会报错。
二、公共字段自动填充
1、在实体类中标记需要自动填充的属性
使用 @TableField(.. fill = FieldFill.INSERT):
/** 创建时间 */
@TableField(value = "created_date",fill = FieldFill.INSERT)
private Date createdDate;
这里的FieldFill用于指定在何种情况自动填充,有如下可选值
DEFAULT:默认不处理
INSERT:插入时自动填充字段
UPDATE:更新时自动填充字段
INSERT_UPDATE:插入和更新时自动填充字段
2、创建自定义处理器MyMetaObjectHandler
这里提供一个简短的例子,以期跑通流程,填充内容和逻辑可结合其它博文自行编写
public class MyMetaObjectHandler extends MetaObjectHandler {
public class MyMetaObjectHandler extends MetaObjectHandler {
/** * 测试 user 表 createdDate 字段为空自动填充 */
@Override
public void insertFill(MetaObject metaObject) {
Object created_by = getFieldValByName("createdBy", metaObject);
if (createdDate == null) {
setFieldValByName("createdDate", new Date(), metaObject);
}
}
}
在本例的mp-plus版本中,此自定义处理器类就是继承MetaObjectHandler,而非实现IMetaObjectHandler,官方文档应该是需要维护而未维护
注意,这里的"createdDate"为实体类内的属性名,不是字段名
3、在Mybatis-Plus配置中注册自定义处理器
若使用DataSourceConfig.java,则在setSqlSessionFactory方法中加入:
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
GlobalConfiguration globalConfig = new GlobalConfiguration();
globalConfig.setMetaObjectHandler(new MyMetaObjectHandler());
bean.setGlobalConfig(globalConfig);
若使用mybatis-config.xml,则
<!-- MyBatis SqlSessionFactoryBean 配置 -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="globalConfig" ref="globalConfig"></property>
</bean>
<bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 公共字段填充处理器 -->
<property name="metaObjectHandler" ref="myMetaObjectHandler" />
</bean>
<!-- 自定义处理器 -->
<bean id="myMetaObjectHandler" class="com.baomidou.test.MyMetaObjectHandler" />
Q.E.D.