`

Ibatis TypeHandler使用总结

    博客分类:
  • Java
阅读更多
ibatis中有一个TypeHandler(准确的说应该是TypeHandlerCallback), 这个接口一般用的比较少, google一下, 大部分就是用来将数据库中的值与java的枚举值或者clob与字符串之间的转换. 最近本人也用到了这个东东. 不过我们使用的是将保存在数据库中以一定分隔符连接的字符串转换成List类型. 开始不知道有TypeHandler这个东东, 于是在JavaBean中定义了两个属性, 一个string类型的, 一个List类型的, 然后内部之间转换, 这种做法有一个弊端, 就是实际上在对一个属性操作的时候, 会有两个接口, 一方面给使用方造成了困惑, 另一个维护起来也不方便, 于是将转换过程完全封装, 对外提供提一个访问接口, 成了一个必要的选择.
先来看看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);


代码很好理解, 而且为了说明如何使用, 作者不惜在注视中给出了一个example.
代码很好理解, setParameter()方法主要是给PrepareStatement赋值. 因此是在insert, update, delete这些操作的时候, 指定传递参数用的.
getResult()方法用来将ResultSet结果集中的内容转换到JavaBean中对应的属性.
valueOf()主要是用来当没有指定的值的时候, 指定默认值的. 主要是ResultSet到JavaBean之间的转换的时候会用到. 最好不要返回null值, 它跟nullValue相关.
下面是一个将数据库中";"分隔的字符串与DO中的list对象之间的转换的实现:
public class PropertiesTypeHandlerCallback implements TypeHandlerCallback {
    private static final String LIST_SPLIT_FLAG = ";";

    public Object getResult(ResultGetter getter) throws SQLException {
        String properties = getter.getString();
        return CollectionUtils.stringToList(properties, LIST_SPLIT_FLAG, new
                StringConvertor<Property>() {
            public Property convert(String str) {
                return Property.valueOf(str);
            }
        });
    }

    @SuppressWarnings("unchecked")
    public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
        List<String> propertyList = (List<String>) parameter;
        setter.setString(CollectionUtils.listToString(propertyList, LIST_SPLIT_FLAG));
    }

    public Object valueOf(String s) {
        return Collections.EMPTY_LIST;
    }
}


接下来是sqlmap的映射文件中进行配置.
针对sql返回结果的转换, 需要在对应的resultMap中指定一下, 比如这样写:
<result property="propertyList" column="PROPERTIES"  typeHandler="com.mysoft.dao.ibatis.support.PropertiesTypeHandlerCallback"/>

针对赋值的参数的设置, 有两种做法, 一种是在parameterMap中的parameter标签中的设置typeHandler属性为对应的callback, 这种做法有一种不好的地方, 就是不同的赋值map, 需要单独定义, 这个反而增加了工作量. 而且使用parameterMap之后, sql语句中的原来在##中指定赋值名称需要改成?, 赋值遵循parameterMap中的定义顺序, 这种做法既繁琐, 可维护性也不好, 因此推荐采用inlineParameter的做法, 比如这样写:
#propertyList,handler=com.taobao.item.dao.ibatis.support.ItemVerticalPropertiesTypeHandlerCallback#


对于TypeHandler的配置, 还有一种做法, 就是在sqlmap中对某一种类型, 使用typeHandler标签进行定义, 比如这样写:
<typeHandler javaType="" callback=""/>

注意这个需要定义在sqlMapConfig标签下.
分享到:
评论
1 楼 Kaede 2011-08-26  
问个问题:

如果在parameter 中指定nullValue,在自定义typeHandler中如何处理。
<parameterMap id="accountTypeHandlerParameterMap" class="account">
 <parameter property="gender" nullValue="male" jdbcType="VARCHAR" typeHandler="com.xxx.post.ext.GenderTypeHandlerCallback"/>
 </parameterMap>


当前gender属性值为空时,报错,com.ibatis.common.jdbc.exception.NestedSQLException: 

相关推荐

Global site tag (gtag.js) - Google Analytics