mybatis-plus是如何只做增强不做改变之通用枚举篇

栏目: Java · 发布时间: 6年前

内容简介:首先,让我们来看张高清无码图,左边两个是mybatis原生的,右边的两个是mybatis-plus的.mybatis-plus通过最好不要将默认枚举类型处理器指定为mybatis-plus的
mybatis-plus是如何只做增强不做改变之通用枚举篇

介绍

首先,让我们来看张高清无码图,左边两个是mybatis原生的,右边的两个是mybatis-plus的.

  • EnumTypeHandler( mybatis包 ) : VARCHAR -任何兼容的字符串类型,存储枚举的名称
  • EnumOrdinalTypeHandler: 任何兼容的 NUMERICDOUBLE 类型,存储枚举的索引
  • EnumAnnotationTypeHandler: 处理自定义枚举属性转换器( 注解方式 ) 枚举类需要标记@EnumValue注解
  • EnumTypeHandler( mybatis-plus包 ): 自定义枚举属性转换器( 非注解方式 ) 枚举类需要实现IEnum接口.

如何配置

  1. mybatis原生配置方式:

    mybatis-plus是如何只做增强不做改变之通用枚举篇
    在mybatis配置中,有一项defaultEnumTypeHandler默认枚举配置,默认使用的EnumTypeHandler( mybatis包

    )

  2. 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"/>
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Blockchain Basics

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 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具