今天在工作中遇到一个问题,公司使用了一个自定义的类型:Money,而数据库是没有这种类型的,对应的数据库字段的类型为BigDecimal.开始时,我没在意这个问题,按照一般的作法写好SQLMAP,运行,发现出了问题,后来仔细一想,发现了这个自定义类型Money的问题,在Ibatis里,是没有默认的方法可以解析或映射我们的自定义类型的.
那怎么办呢,经常一番Google,以及我的聪明才智,最后完美了解决了一个问题.
在Ibatis中,已经提供了解决方案,就是使用Ibatis的TypeHandler , 这种方法呢,其实应该说是有点繁琐,但是,没办法,只能这么做了.
具体办法如下:(本文原创文章,转载时请注明文章来源:巴士飞扬技术博客:原文地址: http://www.busfly.cn/post/Ibatis-java-sql-sqlmap-class.html )
第一步:添加自定义类型Money的TypeHandler类:
/**
* created since 2009-5-11
*/
package com.*.*.*.util;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.ibatis.sqlmap.engine.type.BaseTypeHandler;
import com.ibatis.sqlmap.engine.type.TypeHandler;
/**
* @author busfly http://www.busfly.cn
* @version $Id: MoneyTypeHandler.java,v 0.1 2009-5-11 上午10:58:37 http://www.busfly.cnExp $
*/
public class MoneyTypeHandler extends BaseTypeHandler implements TypeHandler {
//一般,我们都要实现Ibatis提供的接口TypeHandler ,以及直接继承Ibatis提供的父类BaseTypeHandler//从数据库取数据到此自定义类型的方法1
public Object getResult(ResultSet resultset, String columnName) throws SQLException {
Object bigdec = new Money(resultset.getBigDecimal(columnName));
if (resultset.wasNull())
return null;
else
return bigdec;
}
//从数据库取数据到此自定义类型的方法2
public Object getResult(ResultSet resultset, int columnIndex) throws SQLException {
Object bigdec = new Money(resultset.getBigDecimal(columnIndex));
if (resultset.wasNull())
return null;
else
return bigdec;
}
//从数据库取数据到此自定义类型的方法3
public Object getResult(CallableStatement callablestatement, int columnIndex) throws SQLException {
Object bigdec = new Money(callablestatement.getBigDecimal(columnIndex));
if (callablestatement.wasNull())
return null;
else
return bigdec;
}
//从我们的自定义类型变量的值映射到SqlMap时的方法
public void setParameter(PreparedStatement preparedstatement, int i, Object obj, String s) throws SQLException {
preparedstatement.setBigDecimal(i, ((Money) obj).getAmount());//Money.getAmount()方法主我的自定义类型里提供的一个方法,就是将本类的数据转换成BigDecimal类型值.
}
//将查询结果转成我们的自定义类型对象
public Object valueOf(String moneyStr) {
return new Money(moneyStr);
}
}
好了,这个类就写好了,如果还不熟悉的,可以再去看看Ibatis自带的常用类型映射到SqlMap的类(全部在Ibatis包的:com.ibatis.sqlmap.engine.type包下),如BigDecimalTypeHandler,BooleanTypeHandler,ByteArrayTypeHandler,ByteTypeHandler,DoubleTypeHandler等等,里面很多的.
当然也不只能按照上面这么方法写,在看了Ibatis包的:com.ibatis.sqlmap.engine.type包下的类时,发现还有其它的写法,这里就不详细介绍了,但是其写法的麻烦程度不在这个方法之下,有兴趣的朋友可以去看看.
第二步:在你的SQLMAP映射文件里,在相应的映射字段后面都加上 typeHandler="com.*.*.*.util.MoneyTypeHandler" , 如下:
<typeAlias alias="payRecord" type="com.*.*.*.domain.PayRecord" />
<resultMap class="payRecord" id="payRecordResult">
<result column="id" property="id" />
...
<result column="pay_amount" property="payAmount" typeHandler="com.*.*.*.util.MoneyTypeHandler"/>
...
</resultMap>
然后,在功能的SQLMAP方法里,将使用到的这个自定义类型的地方(所有用到的地方都要)都加上:,handler=com.*.*.*.util.MoneyTypeHandler, 如下:
<!-- 插入记录 -->
<insert id="PayRecord.insertPayRecord" parameterClass="payRecord">
<![CDATA[
insert into bankgw_pay_record(...,pay_amount,...)
values(...,#payAmount,handler=com.*.*.*.util.MoneyTypeHandler#,...)
]]>
<selectKey resultClass="long" type="post" keyProperty="id">
select LAST_INSERT_ID() as value
</selectKey>
</insert>
好了,这样两步走就OK了,思路很清晰,说麻烦也不麻烦,说不麻烦,其实也还是很麻烦的,在SQL映射文件里,每个用到这个类型的地方都要进行上面的写法,但是,不管怎样,目前来说,只能这么做了.
Tags: ibatis JAVA SQL |
原创文章如转载,请注明:转载自:巴士飞扬-技术BLOG : http://www.busfly.net/
本文链接地址:http://www.busfly.net/post/Ibatis-java-sql-sqlmap-class.html
如果你喜欢本文,请顶一下,支持我,你的支持是我继续发好文章的最大动力。谢谢。
好东西需要分享,快把本文发给你的朋友吧~!~