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