首先,让我们来看张高清无码图,左边两个是mybatis原生的,右边的两个是mybatis-plus的.
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"/> 复制代码