内容简介:首先,让我们来看张高清无码图,左边两个是mybatis原生的,右边的两个是mybatis-plus的.mybatis-plus通过最好不要将默认枚举类型处理器指定为mybatis-plus的
介绍
首先,让我们来看张高清无码图,左边两个是mybatis原生的,右边的两个是mybatis-plus的.
- EnumTypeHandler( mybatis包 ) : VARCHAR -任何兼容的字符串类型,存储枚举的名称
- EnumOrdinalTypeHandler: 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引
- EnumAnnotationTypeHandler: 处理自定义枚举属性转换器( 注解方式 ) 枚举类需要标记@EnumValue注解
- EnumTypeHandler( mybatis-plus包 ): 自定义枚举属性转换器( 非注解方式 ) 枚举类需要实现IEnum接口.
如何配置
-
mybatis原生配置方式:
在mybatis配置中,有一项defaultEnumTypeHandler默认枚举配置,默认使用的EnumTypeHandler( mybatis包)
-
mybatis-plus配置方式: 参考下官方使用文档吧,比较简单,划个重点( typeEnumsPackage配置 ) 通用枚举使用
源码解读
//MybatisSqlSessionFactoryBean#buildSqlSessionFactory
//判断是否配置了枚举包扫描
if (hasLength(this.typeEnumsPackage)) {
Set<Class> classes;
// 扫描包下的class,这里可以看出支持多个包配置.用,或;进行分隔
if (typeEnumsPackage.contains(StringPool.STAR) && !typeEnumsPackage.contains(StringPool.COMMA)
&& !typeEnumsPackage.contains(StringPool.SEMICOLON)) {
// 配置包含*且不包含,和;
classes = PackageHelper.scanTypePackage(typeEnumsPackage);
if (classes.isEmpty()) {
LOGGER.warn(() -> "Can't find class in '[" + typeEnumsPackage + "]' package. Please check your configuration.");
}
} else {
//按,;进行包配置切割
String[] typeEnumsPackageArray = tokenizeToStringArray(this.typeEnumsPackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Assert.notNull(typeEnumsPackageArray, "not find typeEnumsPackage:" + typeEnumsPackage);
classes = new HashSet<>();
//循环处理包下的class扫描
for (String typePackage : typeEnumsPackageArray) {
Set<Class> scanTypePackage = PackageHelper.scanTypePackage(typePackage);
if (scanTypePackage.isEmpty()) {
LOGGER.warn(() -> "Can't find class in '[" + typePackage + "]' package. Please check your configuration.");
} else {
classes.addAll(PackageHelper.scanTypePackage(typePackage));
}
}
}
// 取得类型转换注册器
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
classes.forEach(cls ->{
//判断当前类是不是枚举类,因为在同个包下,有可能不是枚举,所以跳过非枚举类
if (cls.isEnum()) {
//判断当前枚举类是不是实现类IEnum接口
if (IEnum.class.isAssignableFrom(cls)) {
// 注册上当前类的枚举处理器为EnumTypeHandler
typeHandlerRegistry.register(cls, EnumTypeHandler.class);
} else {
// 非IEnum实现类,反射字段遍历,获取第一个@EnumValue字段
Optional<Field> optional = dealEnumType(cls);
if (optional.isPresent()) {
Field field = optional.get();
field.setAccessible(true);
//缓存下当前类对应的字段----再次划个重点
EnumAnnotationTypeHandler.addEnumType(cls, field);
//注册上当前类的枚举处理器为EnumAnnotationTypeHandler
typeHandlerRegistry.register(cls, EnumAnnotationTypeHandler.class);
}
//这里找不到了的话就会使用默认的mybatis枚举处理器了(配置方式参考后面).
}
}
});
}
//寻找类第一个标记@EnumValue的字段
protected Optional<Field> dealEnumType(Class<?> clazz) {
return clazz.isEnum() ? Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.isAnnotationPresent(EnumValue.class)).findFirst() : Optional.empty();
}
复制代码
总结
mybatis-plus通过 typeEnumsPackage 这属性,来进行枚举类扫描并注册上对应的枚举处理器,在未配置枚举包扫描时或枚举不符合mybaits-plus的注册条件(实现 IEnum 接口或注解 @EnumValue 字段),一律走原生mybatis枚举处理,这项配置可通过设置mybatis的 defaultEnumTypeHandler 来指定.
小提示
最好不要将默认枚举类型处理器指定为mybatis-plus的 EnumAnnotationTypeHandler ,因为这个类在扫描的时候进行了字段的缓存,如果直接将默认枚举处理器指定它,是无法使用的.
指定默认枚举处理器方式
//javaconfig MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class); 复制代码
#yaml
mybatis-plus:
configuration:
default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler
复制代码
<!--xml--> <setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumOrdinalTypeHandler"/> 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- mybatis-plus是如何只做增强不做改变之通用枚举篇(更新版)
- c# – 枚举时项目发生变化时是否会影响枚举?
- 测者的测试技术手册:Junit单元测试遇见的一个枚举类型的坑(枚举类型详解)
- 测者的JUnit单元测试探坑记:Junit单元测试遇见的一个枚举类型的坑(枚举类型详解)
- c# – 循环枚举类型
- Python 的枚举类型
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。