mybatis類型轉換器 - 自定義全局轉換enum


在數據模型、接口參數等場景部分屬性參數為一些常量值,比如性別:男、女。若是定義成int或String類型,於是類型本身的范圍太寬,要求使用者需要了解底層的業務方可知如何傳值,那整體來看增加溝通成本,對接效率也低。面對此等業務,使用枚舉簡便許多。枚舉enum像個固定常量類,也像一個數組。

public enum Sex {
Male(1,"男"),
FeMale(2,"女"),
;
private int index;
private String description;
Sex(int index, String description){
this.index = index;
this.description = description;
}
public int getIndex() {
return index;
}
public String getDescription() {
return description;
}
}

定義枚舉,存儲到數據庫為int。這里就需要使用上mybatis的類型處理器功能。mybatis定義了接口TypeHandler用於數據轉換。

public interface TypeHandler<T> {
void setParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;
T getResult(ResultSet var1, String var2) throws SQLException;
T getResult(ResultSet var1, int var2) throws SQLException;
T getResult(CallableStatement var1, int var2) throws SQLException;
}

mybatis內置了許多類型處理器:IntegerTypeHandlerBigDecimalTypeHandlerEnumTypeHandlerEnumOrdinalTypeHandler

EnumTypeHandler 數據庫字符串類型,用以存儲枚舉的名稱(Male, FeMale);

EnumOrdinalTypeHandler 數據庫為數值類型,存儲枚舉的序數值

從 3.4.5 開始,MyBatis 默認支持 JSR-310(日期和時間 API):LocalDateTypeHandlerLocalDateTimeTypeHandler等。

你可以重寫或自定義實現所需的類型轉換器,實現org.apache.ibatis.type.TypeHandler 接口 或者繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler。

mybatis默認的枚舉實現類,不能把index存入數據庫中,因此需自定義實現器。

在項目定義的枚舉不止一個,若是單個枚舉轉換,代碼成本太高,維護擴展也困難。那有沒有辦法寫一個通用的轉換器呢?

可以的。

一、為了區分那些需要轉換的枚舉,提取些共同屬性,定義成接口,需轉皆實現此接口即可。

public interface BaseEnum{
int getIndex();
String getDescription();
}
public enum Sex implements BaseEnum{
Male(1,"男"),
FeMale(2,"女"),
;
private int index;
private String description;
Sex(int index, String description){
this.index = index;
this.description = description;
}
public int getIndex() {
return index;
}
public String getDescription() {
return description;
}
}

 二、自定義類型轉換器AutoGenericEnumTypeHandler,繼承BaseTypeHandler。因為是通用類型,所以使用到java 泛型的參數


public class AutoGenericEnumTypeHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

private Class<E> enumType;
private E[] enums;

public AutoGenericEnumTypeHandler(){}

public AutoGenericEnumTypeHandler(Class<E> type){
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.enumType = type;
this.enums = type.getEnumConstants();
if (this.enums == null) {
throw new IllegalArgumentException(type.getName() + " does not represent an enum type.");
}
}

private E loadEnum(int index) {
for (E e : enums) {
if (e.getIndex() == index) {
return e;
}
}
throw new IllegalArgumentException(enumType.getName() + " unknown enumerated type index:" + index);
}

@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getIndex());
}

@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
if(rs.getObject(columnName) == null){
return null;
}
int index = rs.getInt(columnName);
return loadEnum(index);
}

@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
if(rs.getObject(columnIndex) == null){
return null;
}
int index = rs.getInt(columnIndex);
return loadEnum(index);
}

@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
if(cs.getObject(columnIndex) == null){
return null;
}
int index = cs.getInt(columnIndex);
return loadEnum(index);
}
}

 三、配置使用。3.4.5版本后提供配置默認枚舉轉換器即,不用侵入寫代碼(侵入寫法源代碼下載路徑:https://gitee.com/zss_376987715/mybatis-dao)

spring boot的配置:mybatis.configuration.default-enum-type-handler=com.XXX.typehandler.AutoGenericEnumTypeHandler

spring項目通過mybatis-config.xml配置文件:

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="defaultEnumTypeHandler" value="com.XXX.typehandler.AutoGenericEnumTypeHandler"/>
</settings>
</configuration>

到此已經實現轉換。

 

如果正在參照(https://www.cnblogs.com/song27/p/10977241.html)學習多數據源。需要對代碼有點改動。

在創建SqlSessionFactory 時,添加MybatisProperties mybatisProperties參數,重新加載configuration。不然spring boot的application.properties配置不會生效。因為未加載進去。


@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource, MybatisProperties mybatisProperties) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setConfiguration(mybatisProperties.getConfiguration());
return sessionFactory.getObject();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM