内容简介:首先,让我们来看张高清无码图,左边两个是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 的枚举类型
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Blockchain Basics
Daniel Drescher / Apress / 2017-3-16 / USD 20.99
In 25 concise steps, you will learn the basics of blockchain technology. No mathematical formulas, program code, or computer science jargon are used. No previous knowledge in computer science, mathema......一起来看看 《Blockchain Basics》 这本书的介绍吧!
Base64 编码/解码
Base64 编码/解码
MD5 加密
MD5 加密工具