我们通常在开发中,有这样的需求:枚举类型存入数据库存的是编码
code
,然而返回给前端的时候是名称name
,我们每次入库的时候都要getCode()
以及返回给前端的时候要getName()
,很繁琐,并且字段属于那种枚举类型的可读性也不高
基于以上问题:我们会尝试着定制一些逻辑专门去处理,一般是自定义枚举转换器实现,然而mybatis-plus提供了优雅的实现方式
接下来我们主要探讨两方面的问题:
- 介绍mybatis-plus通用枚举的使用
- 分析mybatis-plus通用枚举的实现方式
mybatis-plus通用枚举官网传送门
其中有一段关键的说明
解决了繁琐的配置,让 mybatis 优雅的使用枚举属性! 从 3.5.2 版本开始只需完成 步骤1: 声明通用枚举属性 即可使用
@EnumValue
标注入库映射字段@Getter
@AllArgsConstructor
public enum BizType {
/**
* 公告
*/
NOTICE(1, "公告"),
/**
* 项目
*/
PROJECT(2, "项目"),
/**
* 申请
*/
APPLY(3, "申请");
/**
* 编码
*/
@EnumValue
private final int code;
/**
* 名称
*/
@JsonValue
private final String name;
@Override
public String toString() {
return this.name;
}
}
@TableName("mr_resource")
public class ResourceEntity {
/**
* id
*/
private Long id;
/**
* 资源名称
*/
private String name;
/**
* 资源类型
*/
private Integer type;
/**
* 资源大小
*/
private String size;
/**
* 业务类型(直接申明为枚举类型)
*/
private BizType bizType;
@EnumValue:标注该字段是数据库里的字段
@JsonValue:标注该字段要开启自定义序列化返回值
toString:具体的返回值;
/**
* 保存数据库测试
*/
@Test
public void mybatis_enum_ref_add_test() {
ResourceDTO dto = new ResourceDTO();
dto.setBizId(1L);
dto.setBizType(BizType.NOTICE);
dto.setType(1);
dto.setName("测试照片");
resourceService.save(dto);
}
/**
* 查询测试
*/
@Test
public void mybatis_enum_ref_select_test() {
final ResourceEntity resourceEntity = resourceService.selectById(1684833111383851010L);
System.out.println(resourceEntity);
}
IEnum
接口@Getter
@AllArgsConstructor
public enum BizType {
/**
* 公告
*/
NOTICE(1, "公告"),
/**
* 项目
*/
PROJECT(2, "项目"),
/**
* 申请
*/
APPLY(3, "申请");
/**
* 编码
*/
private final int code;
/**
* 名称
*/
@JsonValue
private final String name;
@Override
public String toString() {
return this.name;
}
@Override
public Integer getValue() {
return this.code;
}
}
关于序列化枚举值为前端返回值
上述采用的是注解@JsonValue
+toString()
的方式,还有:全局/局部处理+toString()
的方式
我们采用debug
跟踪一下代码,可以看到在查找枚举BizType
的映射处理器的时候使用了mybatis-plus
复合枚举处理类型CompositeEnumTypeHandler
这里可能我们有疑问,TypeHandlerRegistry.defaultEnumTypeHandler
这个默认枚举处理器是怎么设置进去的了,其实是构建MybatisConfiguration
的时候设置的
接着我们往下debug
可以看到使用了mybatis-plus
中的MybatisEnumTypeHandler
,而MybatisEnumTypeHandler
才是实际处理枚举和数据库字段的映射关系
我们在具体看一下MybatisEnumTypeHandler
是怎么处理的
下面是mybatis-plus
通用枚举相关UML类图