這是個什么問題呢?
首先你要在這樣的環(huán)境下:
iBatis-2.3.4.726
oracle jdbc driver 10.2.0.3.0
你的數(shù)據(jù)庫中字段定義為TIMESTAMP
你的sqlMap中的resultClass為hashmap
這是如果你這樣調(diào)用
Map result = xxxDao.queryForObject(......);
Date someTime = (Date)result.get("someTime");
你會的到如下ClassCaseException: oracle.sql.TIMESTAMP
因為oracle返回的是其自己的TIMESTAMP類型的對象, 而弱智的iBatis, 遇到resultClass為map及其子類型時, 狼心狗肺的, 把數(shù)據(jù)的原始類型原樣返回. 這是是你的到的map里面都是些什么 oracle.sql.DATE, oracle.sql.TIMESTAMP什么的.
怎么辦呢?
難道要這樣?
Date someTime = ((oracle.sql.TIMESTAMP)result.get("someTime")).dateValue();? // <- 這還是java.sql.Date
實在是太ugly了!
其實iBatis在遇到map類型的ResultClass時, 永遠(yuǎn)使用com.ibatis.sqlmap.engine.type.ObjectTypeHandler來做類型轉(zhuǎn)換, 而這個類里的實現(xiàn)卻又是, 永遠(yuǎn)返回JDBC驅(qū)動自己的類型.
這樣只要我們自己寫一個ObjectTypeHandler來代替這個該死的東西不就完事了嗎!
于是乎~~~~
如下:
/**
?*?The?TypeHandler?for?Oracle?JDBC?Driver,?which?fix?the
?*?"oracle.sql.TIMESTAMP?ClassCastException"?problem
?*?
?*?@author?matianyi
?*?
?*/
public?class?OracleObjectTypeHandler?extends?BaseTypeHandler?implements?TypeHandler?{
????/**
?????*?@see?TypeHandler#setParameter(PreparedStatement,?int,?Object,?String)
?????*/
????public?void?setParameter(PreparedStatement?ps,?int?i,?Object?parameter,?String?jdbcType)
throws?SQLException?{
????????ps.setObject(i,?parameter);
????}
????/**
?????*?@see?TypeHandler#getResult(ResultSet,?String)
?????*/
????public?Object?getResult(ResultSet?rs,?String?columnName)?throws?SQLException?{
????????Object?object?=?rs.getObject(columnName);
????????if?(rs.wasNull())?{
????????????return?null;
????????}?else?{
????????????return?fix(object);
????????}
????}
????/**
?????*?@see?TypeHandler#getResult(ResultSet,?int)
?????*/
????public?Object?getResult(ResultSet?rs,?int?columnIndex)?throws?SQLException?{
????????Object?object?=?rs.getObject(columnIndex);
????????if?(rs.wasNull())?{
????????????return?null;
????????}?else?{
????????????return?fix(object);
????????}
????}
????/**
?????*?@see?TypeHandler#getResult(CallableStatement,?int)
?????*/
????public?Object?getResult(CallableStatement?cs,?int?columnIndex)?throws?SQLException?{
????????Object?object?=?cs.getObject(columnIndex);
????????if?(cs.wasNull())?{
????????????return?null;
????????}?else?{
????????????return?fix(object);
????????}
????}
????/**
?????*?@see?TypeHandler#valueOf(String)
?????*/
????public?Object?valueOf(String?s)?{
????????return?s;
????}
????/**
?????* !@#@%$%^$%%!@#%$%^#$%#!%#$^$#%^
?????*?
?????*?@param?obj
?????*???????????? object?from?oracle?jdbc?driver
?????*?@return?object?of?suitable?java?datatype
?????*/
????protected?Object?fix(Object?obj)?{
????????try?{
????????????if?(obj?instanceof?TIMESTAMP)?{
????????????????return?new?Date(((TIMESTAMP)?obj).dateValue().getTime());
????????????}?else?if?(obj?instanceof?DATE)?{
????????????????return?new?Date(((DATE)?obj).dateValue().getTime());
????????????}?else?if?(obj?instanceof?TIMESTAMPLTZ)?{
????????????????return?new?Date(((TIMESTAMPLTZ)?obj).dateValue().getTime());
????????????}?else?if?(obj?instanceof?TIMESTAMPTZ)?{
????????????????return?new?Date(((TIMESTAMPTZ)?obj).dateValue().getTime());
????????????}?else?{
????????????????return?obj;
????????????}
????????}?catch?(Exception?e)?{
????????????return?obj;
????????}
????}
}
上面這個相信大家都回寫! 然后, 關(guān)鍵的來了: 怎么用?
在sqlMapConfig中配一下:
<?xml?version="1.0"?encoding="UTF-8"?>
<!DOCTYPE?sqlMapConfig?PUBLIC?"-//iBATIS.com//DTD?SQL?Map?Config?2.0//EN"
????"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
????<settings?
/>
????<typeHandler?javaType="object"?
????????callback="xxx.xxx.xxx.OracleObjectTypeHandler"/>
????
????<sqlMap??
/>
????
</sqlMapConfig> 這樣就OK了!