SpringBoot多数据源后mybatis枚举转换异常解决方法

一般情况下,SpringBoot会自动配置数据源,引入mybatis配置文件只需要在application.properties里面指定mybatis配置文件路径,简单配置也可以直接在application.properties配置。但是配置完多数据源,若非自动加载的多数据源,则会发现mybatis的配置根本没有起作用。不管你怎么配置,原因是多数据源不是springboot自动配置的,是你手动配置的,无法应用application.properties里面的mybatis配置。怎么解决呢?只需要在配置多数据源时候,指定mybatis配置文件就可以了。

第一步:mybatis枚举转换配置

//这个类是具体枚举的“父类”,都需要实现这个接口,如:public enum xxxEnum implements BaseEnum<Byte>{xxxx}

//接口内容

public interface EnumEntity<T> {
@JsonProperty(“id”)
T getValue();
}

第二步:写一个通用枚举处理类来做枚举处理

public class CommonEnumTypeHandler<E extends Enum<E> & BaseEnum<T>,T> extends BaseTypeHandler<E> {

private Class<E> type;

public CommonEnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException(“Type argument cannot be null”);
}
this.type = type;
}

@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
if (jdbcType == null) {
T id = parameter.getValue();
if(id instanceof Integer || id instanceof Short || id instanceof Character){
ps.setInt(i, (Integer)id);
} else if(id instanceof Byte) {
ps.setByte(i, (Byte) id);
} else if(id instanceof String){
ps.setString(i, (String)id);
}else if(id instanceof Boolean){
ps.setBoolean(i, (Boolean)id);
}else if(id instanceof Long){
ps.setLong(i, (Long)id);
}else if(id instanceof Double){
ps.setDouble(i, (Double)id);
}else if(id instanceof Float){
ps.setFloat(i, (Float)id);
}else{
throw new RuntimeException(“unsupported [id] type of enum”);
}
} else {
ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
}
}

@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
String s = rs.getString(columnName);
return toEnum(s);
}

@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String s = rs.getString(columnIndex);
return toEnum(s);
}

@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String s = cs.getString(columnIndex);
return toEnum(s);
}

private E toEnum(String id){
EnumSet<E> set = EnumSet.allOf(type);
if (set == null || set.size() <= 0) {
return null;
}
for (E e : set) {
T k = e.getValue();
if(k != null){
if(k.toString().equals(id)){
return e;
}
}
}
return null;
}}

第三步:此时已经做完枚举处理了,但是需要在springboot中配置,一般情况下我们这样配置:(非手动配置的多数据源可以这样配置)

#Mybatis配置
mybatis.mapper-locations=classpath:/mapping/**/*Mapper.xml
mybatis.check-config-location=true
mybatis.config-location=classpath:mybatis-config.xml
mybatis.configuration.map-underscore-to-camel-case=true

其中mybatis-config.xml里面内容如下:其中handler就是上面配置的mybatis枚举处理类,javaType就是具体的枚举

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE configuration
PUBLIC “-//mybatis.org//DTD Config 3.0//EN”
“http://mybatis.org/dtd/mybatis-3-config.dtd”>
<configuration>
<settings>
<!–开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。–>
<setting name=”mapUnderscoreToCamelCase” value=”true”/>
</settings>
<typeHandlers>
<typeHandler handler=”so.sao.shop.pay.config.mybatis.CommonEnumTypeHandler” javaType=”so.sao.shop.pay.dto.enums.XxxEnum”/>
</typeHandlers>
</configuration>

如果不是多数据源,其实Springboot配置mybatis枚举处理已经结束了,但是项目中是手动配置的多数据源(配置方式:http://vsalw.com/1421.html ),所以必须进行SqlSessionFactory配置mybatis:重要的红色部分,新加的配置。

@Bean(name = “shopSqlSessionFactory”)
public SqlSessionFactory testSqlSessionFactory(@Qualifier(“shopDataSource”) DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setConfigLocation( new DefaultResourceLoader().getResource(“classpath:mybatis-config.xml”));
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources
(“classpath:mapping/shop/*.xml”));
return bean.getObject();
}

 

其他的不用怎么变,还是一样,但是发现mybatis的枚举转换正常使用了,其实原因就是因为springboot自动配置数据源会使用application.properties中的设置,但是手动自己配置的不会,需要手动指定,问题就出在这里。

 

本站的文章多是老王开发工作中问题的记录,一个字一个字敲的,切实可行,可以分享,需要留个原文链接,至少也意思意思吧!
vsalw技术博客 » SpringBoot多数据源后mybatis枚举转换异常解决方法

你想下载这个主题吗?

沟通一下 扯会蛋