mybatis 列舉自動轉換
阿新 • • 發佈:2019-01-09
基於springboot 整合mybatis tk.mybatis 修改配置沒有生效,只好重寫 EnumTypeHandler 類
springboot 中 mybatis configuration 配置失效問題:https://blog.csdn.net/Keith003/article/details/84289638
結構如下
1、建立 BaseEnums 列舉公用介面
import java.io.Serializable; public interface BaseEnums<E extends Enum<?>,T> extends Serializable { public String getLabel(); public T getValue(); }
2、重寫 EnumTypeHandler 類
package org.apache.ibatis.type; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class EnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> { private BaseTypeHandler typeHandler = null; public EnumTypeHandler(Class<E> type) { if (type == null) { throw new IllegalArgumentException("Type argument cannot be null"); } if(isInterface(type, "BaseEnums介面得全路徑")){ // 如果實現了 BaseEnums 則使用我們自定義的轉換器 typeHandler = new CurrencyEnumHandler(type); }else { // 預設轉換器 也可換成 EnumOrdinalTypeHandler typeHandler = new DefaultEnumTypeHandler<>(type); } } @Override public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException { typeHandler.setNonNullParameter(ps,i, parameter,jdbcType); } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { return (E) typeHandler.getNullableResult(rs,columnName); } @Override public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return (E) typeHandler.getNullableResult(rs,columnIndex); } @Override public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return (E) typeHandler.getNullableResult(cs,columnIndex); } /*************************************************************************** * 判斷物件o實現的所有介面中是否有szInterface * 2008-08-07修正多繼承中判斷介面的功能, * 以及修正介面繼承後的判斷功能 * package test; * * public interfaceITest extends Serializable * public classTest1 implements ITest * public classTest2 extends Test1 * public classTest3 extends Test2 * * isInterface(Test3.class,"java.io.Serializable")=true * isInterface(Test3.class,"test.ITest")=true * @paramc * @paramsz Interface * @return */ public boolean isInterface(Class c, String szInterface) { Class[] face = c.getInterfaces(); for(int i=0,j = face.length; i<j; i++) { if(face[i].getName().equals(szInterface)) { return true; }else { Class[]face1 = face[i].getInterfaces(); for(int x=0; x < face1.length; x++) { if(face1[x].getName().equals(szInterface)) { return true; } else if(isInterface(face1[x],szInterface)) { return true; } } } } if(null!=c.getSuperclass()) { return isInterface(c.getSuperclass(),szInterface); } return false; } }
3、建立 DefaultEnumTypeHandler類 內容為mybatis 中 EnumTypeHandler 類內容 為了不影響除列舉外得轉換
package org.apache.ibatis.type; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DefaultEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> { private final Class<E> type; public DefaultEnumTypeHandler(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) { ps.setString(i, parameter.name()); } else { ps.setObject(i, parameter.name(), jdbcType.TYPE_CODE); // see r3589 } } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { String s = rs.getString(columnName); return s == null ? null : Enum.valueOf(type, s); } @Override public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String s = rs.getString(columnIndex); return s == null ? null : Enum.valueOf(type, s); } @Override public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String s = cs.getString(columnIndex); return s == null ? null : Enum.valueOf(type, s); } }
4、建立 CurrencyEnumHandler類 自定義列舉轉換類
package org.apache.ibatis.type;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* class_name: CurrencyEnumHandler
* package: org.apache.ibatis.type
* describe: 列舉轉換類
* creat_date: 2018/11/19
* creat_time: 10:43
**/
public class CurrencyEnumHandler<E extends Enum<E> & BaseEnums> extends BaseTypeHandler<E>{
private Class<E> type;
/**
* 設定配置檔案設定的轉換類以及列舉類內容,供其他方法更便捷高效的實現
* @param type 配置檔案中設定的轉換類
*/
public CurrencyEnumHandler(Class<E> type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
}
/**
* class_name:
* param:
* describe: 用於定義設定引數時,該如何把 Java 型別的引數轉換為對應的資料庫型別
* creat_date: 2018/11/19
* creat_time: 11:34
**/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter,
JdbcType jdbcType) throws SQLException {
//BaseTypeHandler已經幫我們做了parameter的null判斷
if (jdbcType == null) {
ps.setObject(i, getFieldValueByFieldName("value",parameter));
} else {
ps.setObject(i, getFieldValueByFieldName("value",parameter), jdbcType.TYPE_CODE);
}
}
/**
* class_name:
* param:
* describe: 用於定義通過欄位名稱獲取欄位資料時,如何把資料庫型別轉換為對應的 Java 型別
* creat_date: 2018/11/19
* creat_time: 11:39
**/
@Override
public E getNullableResult(ResultSet rs, String columnName)
throws SQLException {
// 根據資料庫儲存型別決定獲取型別
Object code = rs.getObject(columnName);
return rs.wasNull() ? null : codeOf(code);
}
/**
* class_name:
* param:
* describe: 用於定義通過欄位索引獲取欄位資料時,如何把資料庫型別轉換為對應的 Java 型別
* creat_date: 2018/11/19
* creat_time: 11:41
**/
@Override
public E getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
Object code = rs.getObject(columnIndex);
return rs.wasNull() ? null : codeOf(code);
}
/**
* class_name:
* param:
* describe: 用定義呼叫儲存過程後,如何把資料庫型別轉換為對應的 Java 型別
* creat_date: 2018/11/19
* creat_time: 11:42
**/
@Override
public E getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Object code = cs.getObject(columnIndex);
return cs.wasNull() ? null : codeOf(code);
}
/**
* class_name:
* param:
* describe: 獲取列舉
* creat_date: 2018/11/19
* creat_time: 19:54
**/
private E codeOf(Object code){
try {
Method codeOf = type.getMethod("codeOf", Object.class);
Object invoke = codeOf.invoke(codeOf, code);
return (E)invoke;
} catch (Exception ex) {
throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + " by code value.", ex);
}
}
/**
* 根據屬性名獲取屬性值
*
* @param fieldName
* @param object
* @return
*/
private Object getFieldValueByFieldName(String fieldName, Object object) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
//設定物件的訪問許可權,保證對private的屬性的訪問
field.setAccessible(true);
return field.get(object);
} catch (Exception e) {
return null;
}
}
}
5、建立自己得列舉 實現BaseEnums 介面
package mmall.enums;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* class_name: UpperLowerShelfStateEnum
* package: mmall.enums
* describe: 活動上下架列舉狀態
* 0:待上架 1:上架 2:下架
* creat_date: 2018/11/19
* creat_time: 10:38
**/
public enum UpperLowerShelfStateEnum implements BaseEnums<UpperLowerShelfStateEnum, String> {
To_be_on_the_shelfteacher("待上架","0"),
On_the_shelf("上架","1"),
Lower_frame("下架","2");
private String value;
private String lable;
private UpperLowerShelfStateEnum(String lable, String value) {
this.value = value;
this.lable = lable;
}
@JsonValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getLabel() {
return lable;
}
public void getLabel(String lable) {
this.lable = lable;
}
/**
* 通過value 值進行查詢對應列舉
*/
public static UpperLowerShelfStateEnum codeOf(Object code){
UpperLowerShelfStateEnum[] values = UpperLowerShelfStateEnum.values();
for (UpperLowerShelfStateEnum e : values) {
if (e.getValue().equals(code)) {
return e;
}
}
return null;
}
}
注:本文中向資料庫中儲存得是列舉中value 值 如果需要 可自行修改