mybatis為我們定義了很多自定義的Handler架专,以enum這種特殊類型來講解下如何使用内狗,其他類型的類似處理即可。
EnumTypeHandler
mybatis默認處理enum的Handler锅移,將enum的屬性名映射到數(shù)據(jù)庫中债蜜,處理為字符串梨州。
如果沒有配置typeHandler,遇到enum類型的屬性就會用EnumTypeHandler處理,要用其他的需要配置:
<configuration>
<typeHandlers>
<typeHandler handler="com.demo.test.service.impl.dao.handler.IdEnumHandler"
javaType="com.demo.test.service.type.Module" />
</typeHandlers>
</configuration>
- 值得注意的是诞吱,這里如果配置了jdbcType舟奠,preperStatement時就不會生效了,還是會采用EnumTypeHandler處理房维。(原因暫時沒有深究)
EnumOrdinalTypeHandler
mybatis提供的另一個處理enum的Handler沼瘫,將enum的定義順序下標映射到數(shù)據(jù)庫中,處理為整型握巢。
自定義EnumHandler
我們也可以繼承BaseTypeHandler實現(xiàn)自己的Handler晕鹊,
自定義通用EnumHandler
首先定義一個接口,讓所有要使用這個Handler的enum都實現(xiàn)這個接口暴浦。
public interface IdEnum {
Integer getId();
}
然后可以自定義Handler溅话,主要思路來源于EnumOrdinalTypeHandler,只是他是根據(jù)enum的順序獲得,而我們要定義為根據(jù)某個特殊字段獲得歌焦,所以將他的enum數(shù)組改成Map方便處理飞几。看下他的源碼:
public class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
private Class<E> type;
private final E[] enums;
public EnumOrdinalTypeHandler(Class<E> type) {
if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
/*這行代碼是注入數(shù)組独撇,我們改為Map屑墨,再根據(jù)需求確定key*/
this.enums = type.getEnumConstants();
if (this.enums == null) throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
}
}
自定義通用Handler代碼如下:
public class IdEnumHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
private Class<E> type;
private Map<Integer, E> map = new HashMap<Integer,E>();
public IdEnumHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
E[] enums = type.getEnumConstants();
if (enums == null) {
throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
}
for (E e : enums) {
IdEnum idEnum = (IdEnum) e;
map.put(idEnum.getId(), e);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
IdEnum idEnum = (IdEnum) parameter;
ps.setInt(i, idEnum.getId());
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
return getIdEnum(i);
}
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
int i = rs.getInt(columnIndex);
if (rs.wasNull()) {
return null;
} else {
return getIdEnum(i);
}
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
int i = cs.getInt(columnIndex);
if (cs.wasNull()) {
return null;
} else {
return getIdEnum(i);
}
}
private E getIdEnum(int id) {
try {
return map.get(id);
} catch (Exception ex) {
throw new IllegalArgumentException(
"Cannot convert " + id + " to " + type.getSimpleName() + " by value.", ex);
}
}
}