Oracle中iBatis将结果输出为Map时注意事项
最近碰到一个问题, 在用iBatis访问数据库并采用Map的数据结构返回结果集的时候, 如果是日期类型, 则只会返回日期而没有时间, 不知道哪里出了问题, 经过一番跟踪调试, 发现是jdbc的问题, iBatis内部在将ResultSet转换成Map的时候, 调用的是ResultSet.getObject()方法, 该方法返回的日期时间类型的数据就是没有时间的. 于是google了一下, 发现这里有说明http://www.velocityreviews.com/forums/t146619-p3-date-different.html):
oracle网站上给出的解释:
Oracle JDBC 11.1 fixes this problem. Beginning with this release the driver maps SQL DATE columns to java.sql.Timestamp by default. There is no need to set V8Compatible to get the correct mapping. V8Compatible is strongly deprecated. You should not use it at all. If you do set it to true it won't hurt anything, but you should stop using it.
Although it was rarely used that way, V8Compatible existed not to fix the DATE to Date issue but to support compatibility with 8i databases. 8i (and older) databases did not support the TIMESTAMP type. Setting V8Compatible not only caused SQL DATE to be mapped to Timestamp when read from the database, it also caused all Timestamps to be converted to SQL DATE when written to the database. Since 8i is desupported, the 11.1 JDBC drivers do not support this compatibility mode. For this reason V8Compatible is desupported.
As mentioned above, the 11.1 drivers by default convert SQL DATE to Timestamp when reading from the database. This always was the right thing to do and the change in 9i was a mistake. The 11.1 drivers have reverted to the correct behavior. Even if you didn't set V8Compatible in your application you shouldn't see any difference in behavior in most cases. You may notice a difference if you use getObject to read a DATE column. The result will be a Timestamp rather than a Date. Since Timestamp is a subclass of Date this generally isn't a problem. Where you might notice a difference is if you relied on the conversion from DATE to Date to truncate the time component or if you do toString on the value. Otherwise the change should be transparent.
If for some reason your app is very sensitive to this change and you simply must have the 9i-10g behavior, there is a connection property you can set. Set mapDateToTimestamp to false and the driver will revert to the default 9i-10g behavior and map DATE to Date.
这里给出了三种解决方案:
1.将字段类型由date改成timestamp
2.将defineColumnType设置为Timpstamp而不是Date, 不知道defineColumnType是什么东东
3.不要使用getDate(), 而采用getTimpstamp()
4.使用V8Compatibility连接属性
5.修改java启动参数java -Doracle.jdbc.V8Compatibility="true" MyApp
同样碰到同样的问题看这里(http://jarit.iteye.com/blog/516335)
在外国网站上也看到有人碰到这个问题(http://www.coderanch.com/t/90891/JBoss/oracle-jdbc-V-Compatible-true), 我跟他一样, 设置了jboss的启动参数无效:(
在oracle-ds.xml中设置:
<connection-property name="oracle.jdbc.V8Compatible">true</connection-property>