mybatis枚举自动转换(通用转换处理器实现)

前言

         在上一篇博客,mybatis枚举自动转换实现,已经介绍自动转换的实现步骤,并通过例子告诉大家如何实现枚举的自动转换了。 那么在博客的最后想到,定义一个万能的枚举转换处理器,具体怎么实现呢,相信大神们也应该有思路了,使用泛型实现,没错,就是使用泛型实现,具体请看下面例子。


mybatis万能枚举转换处理器

定义枚举接口

为什么要定义枚举的接口呢,定义接口的好处,其实主要目的是为了在万能枚举转换器中方便泛型的使用,而且还可以规范枚举类的实现。
package net.itaem.less;

/**
 * @author: Fighter168
 */
public interface BaseEnum<E extends Enum<?>, T> {
	public T getValue();
	public String getDisplayName();
}


实现枚举接口,定义枚举

实现BaseEnum接口,定义PersonType枚举
package net.itaem.less;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: Fighter168
 */
public enum PersonType implements BaseEnum<PersonType, String>{ 
	student("1","学生"),
	teacher("2","教师");
	
	private String value;
	private String displayName;
	
	static Map<String,PersonType> enumMap=new HashMap<String, PersonType>();
	static{
		for(PersonType type:PersonType.values()){
			enumMap.put(type.getValue(), type);
		}
	}
	
	private PersonType(String value,String displayName) {
		 this.value=value;
		 this.displayName=displayName;
	}
	
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public String getDisplayName() {
		return displayName;
	}
	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}
	
	public static PersonType getEnum(String value) {
		return enumMap.get(value);
	}
}


定义万能枚举转换处理器

package net.itaem.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import net.itaem.less.BaseEnum;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

/**
 * @author: Fighter168
 */
public final class UniversalEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

	private Class<E> type;
	private E [] enums;
	
    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     * @param type 配置文件中设置的转换类
     */
    public UniversalEnumHandler(Class<E> 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.");
    }
	
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, E parameter,
			JdbcType jdbcType) throws SQLException {
		//BaseTypeHandler已经帮我们做了parameter的null判断
	    ps.setObject(i,(String)parameter.getValue(), jdbcType.TYPE_CODE); 
	}

	@Override
	public E getNullableResult(ResultSet rs, String columnName)
			throws SQLException {
		// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
        String i = rs.getString(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的value值,定位PersonType子类
            return locateEnumStatus(i);
        }
	}

	@Override
	public E getNullableResult(ResultSet rs, int columnIndex)
			throws SQLException {
		// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
        String i = rs.getString(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的value值,定位PersonType子类
            return locateEnumStatus(i);
        }
	}

	@Override
	public E getNullableResult(CallableStatement cs, int columnIndex)
			throws SQLException {
		// 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
        String i = cs.getString(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的value值,定位PersonType子类
            return locateEnumStatus(i);
        }
	}

	 /**
     * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
     * @param value 数据库中存储的自定义value属性
     * @return value对应的枚举类
     */
    private E locateEnumStatus(String value) {
        for(E e : enums) {
            if(e.getValue().equals(value)) {
                return e;
            }
        }
        throw new IllegalArgumentException("未知的枚举类型:" + value + ",请核对" + type.getSimpleName());
    }
}



测试

           接下来,我们就修改原来的例子(上一篇博客的例子: mybatis枚举自动转换实现),只需修改typeHandler,修改成
   	 <typeHandler handler="net.itaem.handler.UniversalHandler"
   		 javaType="net.itaem.less.PersonType" jdbcType="CHAR"/>
然后我们再次运行测试用例,会发现,我们的查询得到的结果还是一样,这样,我们就不需要为每一个枚举创建一个Handler去自动转换数据库中的枚举了。




自动扫描枚举注册想法

             做到这里,或许我们又想了,要是我们一个项目特别大,有几十个甚至是上百个枚举呢,那怎么办,难道我要一个个在typeHandler里面去加,加一百几十行?!个人觉得非常麻烦,影响我们的开发速度,so,能不能实现我们想要的像扫描下枚举的所在的包目录就可以注册的枚举做自动转换呢?具体怎么实现?下篇博客我会教大家如何实现。












  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值