iBATIS的自定义类型处理器TypeHandlerCallback

http://macrochen.iteye.com/blog/526258

BATIS提供TypeHandlerCallback来提供对用户自定义类型的处理。
Java代码 
public interface TypeHandlerCallback { 
 
    public void setParameter(ParameterSetter setter, Object parameter) 
      throws SQLException; 
 
  public Object getResult(ResultGetter getter) 
      throws SQLException; 
 
   public Object valueOf(String s); 
 


它主要利用上述的三个方法来对自定义类型转换提供支持。下面我详细讲述下如何利用其来对自定义数据进行支持。
演示的内容主要是将表单中gender列中的字段转换为自己需要的内容(female<->女,male<->男)
1.数据库表people
Sql代码 
create table people( 
id int not null auto_increment,  
gender varchar(10), 
constraint pk primary key(id)  
); 
 
insert into people(id,gender) values (null,'female'); 
insert into people(id,gender) values (null,male); 
insert into people(id,gender) values (null,null);  

  表单很简单,主要提供一个自增主键和一个可以为null的性别,并插入了实验数据。
2.POJO类
Java代码 
package com.xxx.pojos; 
public class People{ 
 
    private int id; 
 
    private String gender; 
 
    /**
     * @return the id
     */ 
    public int getId() { 
        return id; 
    } 
 
    /**
     * @param id
     *            the id to set
     */ 
    public void setId(int id) { 
        this.id = id; 
    } 
 
    /**
     * @return the gender
     */ 
    public String getGender() { 
        return gender; 
    } 
 
    /**
     * @param gender
     *            the gender to set
     */ 
    public void setGender(String gender) { 
        this.gender = gender; 
    } 
 
    @Override 
    public String toString() { 
        return "id:" + id + "  gender:" + gender; 
    } 
 

 
3.TypeHandlerCallback实现类
Java代码 
public class GenderTypeHandlerCallback implements TypeHandlerCallback { 
 
    private static final String R_FEMALE = "女"; 
 
    private static final String R_MALE = "男"; 
 
    private static final String FEMALE = "female"; 
 
    private static final String MALE = "male"; 
 
    /**
     * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#getResult(com.ibatis.sqlmap.client.extensions.ResultGetter)
     */ 
    public Object getResult(ResultGetter getter) throws SQLException { 
 
        if (getter.getObject() == null) 
        { 
            return null; 
        } 
 
        return convertDbToValue(getter.getString()); 
    } 
 
    /**
     * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#setParameter(com.ibatis.sqlmap.client.extensions.ParameterSetter,
     *      java.lang.Object)
     */ 
    public void setParameter(ParameterSetter setter, Object value) 
            throws SQLException { 
 
        setter.setString(saveValueToDb((String) value)); 
 
    } 
 
    /**
     * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#valueOf(java.lang.String)
     */ 
    public Object valueOf(String value) { 
 
        return convertDbToValue(value); 
    } 
 
    /**
     * 将POJO中的值转换数据库值存储
     * 
     * @param value
     * @return
     */ 
    private String saveValueToDb(String value) { 
        if (value.equals(R_MALE)) 
        { 
            return FEMALE; 
        } else if (value.equals(R_FEMALE)) 
        { 
            return MALE; 
        } else 
        { 
            throw new IllegalArgumentException("参数值不正确!" + value); 
        } 
    } 
 
    /**
     * 将数据库的值转换为POJO所需要的值
     * 
     * @param value
     * @return
     */ 
    private String convertDbToValue(String value) { 
 
        if (value.equals(FEMALE)) 
        { 
            return R_FEMALE; 
        } else if (value.equals(MALE)) 
        { 
            return R_MALE; 
        } else 
        { 
            throw new IllegalArgumentException("参数值不正确!" + value); 
        } 
    } 
 

4.注册TypehandlerCallback
  可以在多个配置文件中进行注册:
  1).sqlMapConfig.xml。全局配置注册.
  2)单独的parameterMap或resultMap中注册。
  本例主要演示在parameterMap中进行注册
Xml代码 
<resultMap class="com.xxx.pojos.People" id="people"> 
  <result property="id" column="id" javaType="int" jdbcType="INT"/> 
  <result property="gender" column="gender" javaType="string"   nullValue="male" jdbcType="VARCHAR"  typeHandler="com.xxx.typeHandler.GenderTypeHandlerCallback" /> 
   
</resultMap> 
5.运行结果
   可以发现,原本在数据库中存储中gender列内容为female,male和null,但是经过自定义类型转换后相应变成了男或女。
  6.遇到的问题
    上述内容经过我测试没有任何问题,不过我在看到相关资料时却出现了一个问题:
   在TypeHandlerCallback方法中,存在一个valueOf()方法,其主要作用是当数据库中列可以为空(null)时进行处理。相应地,你需要在注册时在result的nullValue中填写为空时的默认值,如上面的nullValue="male"。
  此外,还需要特别注意的一点就是:即使你在注册时填写了nullValue='male',仍然会出现NUllpointer异常,并且跟踪发现valueOf方法没有被调用,解决方法是在getResult方法中添加 if (getter.getObject() == null) { return null; }
即需要你手动判断一次是否为null,当其结果返回null时才有会调用valueOf方法载入所设置的nullValue的值。

你可能感兴趣的:(TypeHandler)