内容简介:首先,让我们来看张高清无码图,左边两个是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 的枚举类型
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
驾驭未来:抓住奇点冲击下的商机
[日]斋藤和纪 / 南浩洁 / 中国友谊出版公司 / 2018-9 / 52.00元
2020年左右,AI(人工智能)将超越人类的智力水平。2045年,人类将迎来“奇点”——科技进步的速度达到无限大。 所有技术都在以空前的速度向前发展。同时,以往带来巨大财富的众多技术将走向“非货币化”。当下,人类正面临着被AI夺去工作的危机。许多传统行业(例如汽车制造业)将被彻底颠覆,但新的机会也在酝酿,技术的进步使得带宽成本、计算成本、存储成本等创新成本趋近于0,创业不再是资本、技术或信息......一起来看看 《驾驭未来:抓住奇点冲击下的商机》 这本书的介绍吧!