iBATIS的自定义类型处理器TypeHandlerCallback解决乱码

转自:http://jackandroid.iteye.com/blog/614032

iBATIS的自定义类型处理器TypeHandlerCallback

BATIS提供TypeHandlerCallback来提供对用户自定义类型的处理。

Java代码  收藏代码
  1. public interface TypeHandlerCallback {  
  2.   
  3.     public void setParameter(ParameterSetter setter, Object parameter)  
  4.       throws SQLException;  
  5.   
  6.   public Object getResult(ResultGetter getter)  
  7.       throws SQLException;  
  8.   
  9.    public Object valueOf(String s);  
  10.   
  11. }  

它主要利用上述的三个方法来对自定义类型转换提供支持。下面我详细讲述下如何利用其来对自定义数据进行支持。

演示的内容主要是将表单中gender列中的字段转换为自己需要的内容(female<->女,male<->男)

1.数据库表people

Sql代码  收藏代码
  1. create table people(  
  2.  id int not null auto_increment,   
  3.  gender varchar(10),  
  4.  constraint pk primary key(id)   
  5. );  
  6.   
  7.  insert into people(id,gender) values (null,'female');  
  8.  insert into people(id,gender) values (null,male);  
  9.  insert into people(id,gender) values (null,null);   

  表单很简单,主要提供一个自增主键和一个可以为null的性别,并插入了实验数据。

2.POJO类

Java代码  收藏代码
  1. package com.xxx.pojos;  
  2. public class People{  
  3.   
  4.     private int id;  
  5.   
  6.     private String gender;  
  7.   
  8.     /** 
  9.      * @return the id 
  10.      */  
  11.     public int getId() {  
  12.         return id;  
  13.     }  
  14.   
  15.     /** 
  16.      * @param id 
  17.      *            the id to set 
  18.      */  
  19.     public void setId(int id) {  
  20.         this.id = id;  
  21.     }  
  22.   
  23.     /** 
  24.      * @return the gender 
  25.      */  
  26.     public String getGender() {  
  27.         return gender;  
  28.     }  
  29.   
  30.     /** 
  31.      * @param gender 
  32.      *            the gender to set 
  33.      */  
  34.     public void setGender(String gender) {  
  35.         this.gender = gender;  
  36.     }  
  37.   
  38.     @Override  
  39.     public String toString() {  
  40.         return "id:" + id + "  gender:" + gender;  
  41.     }  
  42.   
  43. }  

  

3.TypeHandlerCallback实现类 

Java代码  收藏代码
  1. public class GenderTypeHandlerCallback implements TypeHandlerCallback {  
  2.   
  3.     private static final String R_FEMALE = "女";  
  4.   
  5.     private static final String R_MALE = "男";  
  6.   
  7.     private static final String FEMALE = "female";  
  8.   
  9.     private static final String MALE = "male";  
  10.   
  11.     /** 
  12.      * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#getResult(com.ibatis.sqlmap.client.extensions.ResultGetter) 
  13.      */  
  14.     public Object getResult(ResultGetter getter) throws SQLException {  
  15.   
  16.         if (getter.getObject() == null)  
  17.         {  
  18.             return null;  
  19.         }  
  20.   
  21.         return convertDbToValue(getter.getString());  
  22.     }  
  23.   
  24.     /** 
  25.      * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#setParameter(com.ibatis.sqlmap.client.extensions.ParameterSetter, 
  26.      *      java.lang.Object) 
  27.      */  
  28.     public void setParameter(ParameterSetter setter, Object value)  
  29.             throws SQLException {  
  30.   
  31.         setter.setString(saveValueToDb((String) value));  
  32.   
  33.     }  
  34.   
  35.     /** 
  36.      * @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#valueOf(java.lang.String) 
  37.      */  
  38.     public Object valueOf(String value) {  
  39.   
  40.         return convertDbToValue(value);  
  41.     }  
  42.   
  43.     /** 
  44.      * 将POJO中的值转换数据库值存储 
  45.      *  
  46.      * @param value 
  47.      * @return 
  48.      */  
  49.     private String saveValueToDb(String value) {  
  50.         if (value.equals(R_MALE))  
  51.         {  
  52.             return FEMALE;  
  53.         } else if (value.equals(R_FEMALE))  
  54.         {  
  55.             return MALE;  
  56.         } else  
  57.         {  
  58.             throw new IllegalArgumentException("参数值不正确!" + value);  
  59.         }  
  60.     }  
  61.   
  62.     /** 
  63.      * 将数据库的值转换为POJO所需要的值 
  64.      *  
  65.      * @param value 
  66.      * @return 
  67.      */  
  68.     private String convertDbToValue(String value) {  
  69.   
  70.         if (value.equals(FEMALE))  
  71.         {  
  72.             return R_FEMALE;  
  73.         } else if (value.equals(MALE))  
  74.         {  
  75.             return R_MALE;  
  76.         } else  
  77.         {  
  78.             throw new IllegalArgumentException("参数值不正确!" + value);  
  79.         }  
  80.     }  
  81.   
  82. }  

 4.注册TypehandlerCallback

  可以在多个配置文件中进行注册:

  1).sqlMapConfig.xml。全局配置注册.

  2)单独的parameterMap或resultMap中注册。

  本例主要演示在parameterMap中进行注册

Xml代码  收藏代码
  1. <resultMap class="com.xxx.pojos.People" id="people">  
  2.   <result property="id" column="id" javaType="int" jdbcType="INT"/>  
  3.   <result property="gender" column="gender" javaType="string"   nullValue="male" jdbcType="VARCHAR"  typeHandler="com.xxx.typeHandler.GenderTypeHandlerCallback" />  
  4.     
  5. </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的值。

原文地址:https://www.cnblogs.com/summer520/p/3328323.html