mybatis枚举自动转换实现

前言

           在设计数据库的时候,我们有时候会把表里的某个字段的值设置为数字或者为英文来表示他的一些特殊含义。就拿设置成数字来说,假如1对应是学生,2对应是教师,在java里面定义成这样的枚举,但是一般使用mybatis查出来的话,我们想要让它自动装换成我们想要的枚举,不需要再手动根据数值去判断设置成我们想要的枚举。要是实现这样的效果,那么我们就要用到mybatis的BaseTypeHandler了。

           

BaseTypeHandler介绍

             让我们来看看要继承BaseTypeHandler这个抽象类,需要覆写哪些方法:

  public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

  public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

  public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

实现了这些抽象类,当得到结果集的时候,程序就会回调这些方法,例如根据名称获取当前行的某一列的值,那么就会直接回调getNullableResult(ResultSet rs, String columnName)这个方法,根据名称得到当行的当前列的值,然后我们在这里去调用枚举,匹配枚举中的每一个值,相等的话直接返回该枚举,达到自动转换成我们想要的枚举的效果。其他的重载方法类似,只不过是有些根据列索引,有些根据列名称做枚举自动转换而已。

好了,介绍就到这里,让我们来看看具体实现。。



自动转换实现例子

创建数据库表

mybatis枚举自动转换实现_第1张图片


创建枚举

package net.itaem.less;

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

/**
 * @author: Fighter168
 */
public enum PersonType{ 
	STUDENT("1","学生"),
	TEACHER("2","教师");
	
	private String value;
	private String displayName;
	
	static Map enumMap=new HashMap();
	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);
	}
}




创建Po实体类

/**
 * @author: Fighter168
 */
public class Person {
	private String id;
	private String name;
	//枚举
	private PersonType personType;
        //set get 方法。。
}


创建Dao接口

创建一个简单的测试dao,这里简单的提供一个测试的查询方法。

/**
 * @author: Fighter168
 */
public interface PersonDao {

	public List query();

}

创建枚举转换处理器

package net.itaem.handler;

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

import net.itaem.less.PersonType;

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

/**
 * @author: Fighter168
 */
public class PersonTypeHandler extends BaseTypeHandler{

	private Class type;

    private  PersonType[] enums;
    
    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     * @param type 配置文件中设置的转换类
     */
    public PersonTypeHandler(Class 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 PersonType getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
        String i = rs.getString(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的value值,定位PersonType子类
            return PersonType.getEnum(i);
        }
    }

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

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

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, PersonType parameter, JdbcType jdbcType)
            throws SQLException {
        // baseTypeHandler已经帮我们做了parameter的null判断
        ps.setString(i, parameter.getValue());

    }
	
}



创建Mapper映射文件

PersonDao对应的PersonMapper映射文件




  
  
	    
	    
	    
  
 
 
  
其实handler还可以写在PersonMapper.xml这里,写成下面这样:

	    





创建Spring的配置文件



	  
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	     
	
	
	
		
		
	
 
	 
		  
	 

创建mybatis的配置文件

下面是为mybatis创建配置文件cfg.xml

  
  
  
    
   	 
    
      
      
          
      

创建测试用例

/**
 * @author: Fighter168
 */
public class SpringTest {

	public static void main(String[] args) {
		ApplicationContext context=new ClassPathXmlApplicationContext("resource/ApplicationContext.xml");
		PersonDao personDao=(PersonDao) context.getBean("personDao");
		List list=personDao.query();
		for(Person p:list){
			System.out.println(p.toString());
		}
	}
}

测试结果展示

结果是成功自动转换成了我们想要的枚举

mybatis枚举自动转换实现_第2张图片



万能枚举转换处理器?

             也许我们还在想,如果我们有几十个枚举,这样转换的话,那我们岂不是要分别为每一个枚举定义一个Handler,然后为每一个Handler注册。其实不必这样,我们可以定义成一个通用的枚举转换处理器,具体怎么实现呢,下一篇博客我会告诉大家   mybatis枚举自动转换(通用转换处理器实现)



你可能感兴趣的:(mybatis,mybatis)