欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iBATIS的自定义类型处理器TypeHandlerCallback

程序员文章站 2022-05-23 12:54:49
...

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

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

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类

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实现类 

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中进行注册

 
 <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的值。

 

 

 

 

 

相关标签: iBATIS