typehandler的使用

在iBatis中(现在已经更名为mybatis),当要实现在某个数据表字段和POJO的
property之间做特殊类型的转换时,如果两个类型转换不是iBatis默认支持的,需
要自己实现一个TypeHandler来满足要求。TypeHandler是iBatis中定义的接口
public interface TypeHandler {
  public void setParameter(PreparedStatement ps, int i, Object
parameter, String jdbcType)
      throws SQLException;

  public Object getResult(ResultSet rs, String columnName)
      throws SQLException;

  public Object getResult(ResultSet rs, int columnIndex)
      throws SQLException;

  public Object getResult(CallableStatement cs, int columnIndex)
      throws SQLException;

  public Object valueOf(String s);

  public boolean equals(Object object, String string);

}

从接口定义可以看出很简单,就是定义了如何在DB和POJO直接对属性值做转换。

假设我们还是要实现一个enum到boolean的转换,我这里写了一个,大家可以简单
看一下写法就知道自己需要的时候要做哪些事情了,其中BaseTypeHandler是
iBatis提供的一个基类:
public class StringBooleanTypeHandler extends BaseTypeHandler implements
TypeHandler {

          public void setParameter(PreparedStatement ps, int i, Object
        parameter, String jdbcType)
              throws SQLException {
            ps.setString(i, ((Boolean) parameter).toString());
          }

          public Object getResult(ResultSet rs, String columnName)
              throws SQLException {
            Object s = rs.getString(columnName);
            if (rs.wasNull()) {
              return null;
            } else {
              return Boolean.valueOf((String)s);
            }
          }

          public Object getResult(ResultSet rs, int columnIndex)
              throws SQLException {
            Object s = rs.getString(columnIndex);
            if (rs.wasNull()) {
              return null;
            } else {
              return Boolean.valueOf((String)s);
            }
          }

          public Object getResult(CallableStatement cs, int columnIndex)
              throws SQLException {
            Object s = cs.getString(columnIndex);
            if (cs.wasNull()) {
              return null;
            } else {
              return Boolean.valueOf((String)s);
            }
          }

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

        }


如何在iBatis中配置这个自己的TypeHandler呢?有两种方法:
先假设我在sqlMapConfig.xml中给自定义的Handler声明了别名
<typeAlias type="cn.vobile.cyberlocker.dao.StringBooleanTypeHandler"
alias="myHandler" />
(1)对于使用不频繁的情况,可以只在需要的地方声明自己的handler。
如果使用ParamerterMap,就是在子元素ParameterMapping里面声明;
如果使用ParameterClass,那就是在InlineParameter里面声明,这样写:
INSERT INTO matchedFile (company_id, trackingWebsite_id, file_uuid,
clip_title, source_url, page_info, password, contributor,
matchedFileItem_count, is_appended, created_at)
        VALUES (#companyId#, #websiteId#,UUID(), #clipTitle#, #sourceUrl#,
#pageInfo#, #password#, #contributor#, #matchedFileItemCount#,
#isAppended,handler=myHandler#, NOW())
注意,这里#isAppended,handler=myHandler#,这样就声明好了。但不要在,和
handler中间留空格,否则通不过
对于ResultMap,一样在ResultMapping中声明就好了,如:
<result column="is_refreshing" property="isRefreshing" jdbcType="CHAR"
javaType="boolean"  typeHandler=“myHandler"/>

(2)对于很多地方都要用到的handler,建议在sqlMapConfig.xml中声明,免得每处
都要写。如:
<typeHandler javaType="boolean" jdbcType="VARCHAR"
callback="myHandler" />


这里我个人建议写上jdbcType="VARCHAR",网上或着文档上很多就只写了
javaType="boolean"一个的。如果不写的话,很容易造成自己写的typeHandler把
iBatis默认的替换掉,引起不必要的问题。具体的原理我就不写了,设计到iBatis
的实现,太啰嗦。

你可能感兴趣的:(xml,ibatis)