内置的枚举处理器
mybatis内置了两个枚举类型处理器,EnumTypeHandler和EnumOrdinalTypeHandler,这两个类型都不好用,一般也是我们自己实现枚举的类型处理器。
EnumTypeHandler存入数据库的是枚举的name,EnumOrdinalTypeHandler存入数据库的是枚举的位置。例如下方的枚举,当我们有一个枚举值是EStatus.init时,这时我们使用mybatis的EnumTypeHandler存入数据库的是”init”字符串;而EnumOrdinalTypeHandler存入的是3,因为init是第四个值,第一个值disable的index是0。
public enum EStatus {
disable("0"), enable("1"), deleted("2"),
init("10"), start("11"), wait("12"), end("13");
}
编写枚举接口约束
首先定义接口,提供获取数据库存取的值得方法,方便多个枚举,使用一个Handler处理
package com.join.payment.utils;
/**
* 枚举约束
*/
public interface BaseCodeEnum {
int getCode();//必须包含方法
}
编写 EnumTypeHandler
定义mybatis的typeHandler扩展类
package com.join.payment.utils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 通用int 枚举转换器
* @author 范文刚
*/
public class EnumTypeHandler extends BaseTypeHandler<BaseCodeEnum>{
private Class<BaseCodeEnum> type;
private final BaseCodeEnum[] enums;
/**
* 设置配置文件设置的转换类以及枚举类内容,供其余方法更便捷高效的实现
* @param type 配置文件中设置的转换类
*/
public EnumTypeHandler(Class<BaseCodeEnum> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
this.enums = type.getEnumConstants();
if (this.enums == null) {
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
}
/**
* 枚举类型转换,因为构造函数获取了枚举的子类enums,让遍历更加高效快捷
* @param code 数据库中存储的自定义code属性
* @return code对应的枚举类
*/
private BaseCodeEnum locateEnumStatus(int code) {
for(BaseCodeEnum status : enums) {
if(status.getCode() ==code ) {
return status;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, BaseCodeEnum parameter, JdbcType jdbcType) throws SQLException {
// baseTypeHandler已经作了parameter的null判断
ps.setInt(i, parameter.getCode());
}
@Override
public BaseCodeEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumStatus子类
return locateEnumStatus(i);
}
}
@Override
public BaseCodeEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnIndex);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumStatus子类
return locateEnumStatus(i);
}
}
@Override
public BaseCodeEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = cs.getInt(columnIndex);
if (cs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位EnumStatus子类
return locateEnumStatus(i);
}
}
}
举个OrderStateEnumde例子
package com.join.payment.domain;
import com.join.payment.utils.BaseCodeEnum;
/**
* 订单状态
* @author 范文刚
*/
public enum OrderStateEnum implements BaseCodeEnum {
/**
* 交易关闭
*/
CLOSE(-1),
/**
* 默认
*/
DEFAULT(0),
/**
* 交易中
*/
APPLY(1),
/**
* 交易成功
*/
SUCCESS(2);
OrderStateEnum(int code)
{
this.code = code;
}
private final int code;
@Override
public int getCode(){ return code; }
}
Mapper 文件中修改处理器
<resultMap type="PayOrder" id="PayOrderResult">
<result property="id" column="id" />
<result property="state" column="state" typeHandler="com.join.payment.utils.EnumTypeHandler" />
</resultMap>
<insert id="insertPayOrder" parameterType="PayOrder">
insert into pay_order
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if>
<if test="state != null">state,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
<if test="state != null">#{state,typeHandler=com.join.payment.utils.EnumTypeHandler},</if>
</trim>
</insert>
<update id="updatePayOrder" parameterType="PayOrder">
update pay_order
<trim prefix="SET" suffixOverrides=",">
<if test="state != null">state = #{state,typeHandler=com.join.payment.utils.EnumTypeHandler},
</trim>
where id = #{id}
</update>