`

Oracle中iBatis将结果输出为Map时注意事项

阅读更多
最近碰到一个问题, 在用iBatis访问数据库并采用Map的数据结构返回结果集的时候, 如果是日期类型, 则只会返回日期而没有时间, 不知道哪里出了问题, 经过一番跟踪调试, 发现是jdbc的问题, iBatis内部在将ResultSet转换成Map的时候, 调用的是ResultSet.getObject()方法, 该方法返回的日期时间类型的数据就是没有时间的. 于是google了一下, 发现这里有说明http://www.velocityreviews.com/forums/t146619-p3-date-different.html):
oracle网站上给出的解释:
引用
Simple Data Types What is going on with DATE and TIMESTAMP?
This section is on simple data types. :-)

Prior to 9.2, the Oracle JDBC drivers mapped the DATE SQL type to java.sql.Timestamp. This made a certain amount of sense because the Oracle DATE SQL type contains both date and time information as does java.sql.Timestamp. The more obvious mapping to java.sql.Date was somewhat problematic as java.sql.Date does not include time information. It was also the case that the RDBMS did not support the TIMESTAMP SQL type, so there was no problem with mapping DATE to Timestamp.

In 9.2 TIMESTAMP support was added to the RDBMS. The difference between DATE and TIMESTAMP is that TIMESTAMP includes nanoseconds and DATE does not. So, beginning in 9.2, DATE is mapped to Date and TIMESTAMP is mapped to Timestamp. Unfortunately if you were relying on DATE values to contain time information, there is a problem.

There are several ways to address this problem in the 9.2 through 10.2 drivers:

Alter your tables to use TIMESTAMP instead of DATE. This is probably rarely possible, but it is the best solution when it is.

Alter your application to use defineColumnType to define the columns as TIMESTAMP rather than DATE. There are problems with this because you really don't want to use defineColumnType unless you have to (see What is defineColumnType and when should I use it?).

Alter you application to use getTimestamp rather than getObject. This is a good solution when possible, however many applications contain generic code that relies on getObject, so it isn't always possible.

Set the V8Compatible connection property. This tells the JDBC drivers to use the old mapping rather than the new one. You can set this flag either as a connection property or a system property. You set the connection property by adding it to the java.util.Properties object passed to DriverManager.getConnection or to OracleDataSource.setConnectionProperties. You set the system property by including a -D option in your java command line.

java -Doracle.jdbc.V8Compatible="true" MyApp
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>

也是无效的
分享到:
评论
1 楼 flynofry 2013-05-14  
java -Doracle.jdbc.V8Compatibility="true"

你妈的,是个错的
是这个  -Doracle.jdbc.V8Compatible="true"

相关推荐

    ibatis+oracle实例

    在IT行业中,数据库管理和持久化框架是至关重要的技术领域,而`ibatis+oracle`的组合就是这样的一个经典实例。Ibatis,一个轻量级的Java ORM(对象关系映射)框架,允许开发者将SQL语句与Java代码分离,提高了数据库...

    一个完整的oracle+ibatis小项目

    Oracle 和 iBatis 是两个在 Java Web 开发中广泛应用的技术。Oracle 是一款强大的关系型数据库管理系统,而 iBatis 是一个优秀的持久层框架,它能够将 SQL 与 Java 代码分离,提供更灵活的数据库访问方式。在这个"一...

    oracle 的ibatis驱动程序包

    包含了ibatis及jdbc的驱动,需要的可以下载

    ibatis oracle clob

    2. **读取CLOB数据**:在查询返回结果中,iBATIS会自动处理CLOB类型,将其转化为String。但是,由于CLOB可能包含大量数据,因此在处理时需要考虑性能问题,避免一次性加载整个CLOB到内存中。 3. **事务管理**:由于...

    ORACLE、IBATIS_20100914

    ORACLE、IBATIS_20100914 ORACLE、IBATIS_20100914 ORACLE、IBATIS_20100914

    iBATIS操作Oracle CLOB数据

    在Oracle中,CLOB通常用于存储大段的文本,如文章、报告或者XML文档。 iBATIS是一个Java库,它允许开发者将SQL语句与Java代码分离,提供了一种比JDBC更简单的数据访问方法。iBATIS的配置文件和映射文件中,我们可以...

    Ibatis.net+ oracle 简单事例

    添加对Oracle 的引用,如Oracle.DataAccess.Client,然后将Ibatis.net 的相关配置文件和Mapper XML文件加入到项目中。使用VS2008的调试工具,可以快速测试SQL语句和业务逻辑。 【示例应用】 "IbatisTet" 可能是一个...

    ibatis调用oracle存储过程

    本文将深入解析ibatis如何与Oracle数据库中的存储过程进行交互,通过具体示例详解配置与实现步骤。 ### ibatis简介 ibatis,现称为MyBatis,是一个支持普通SQL查询、存储过程以及高级映射的优秀持久层框架。它消除...

    oracle ibatis 配置

    Oracle 和 iBatis 是两个在 Java 开发中广泛使用的数据库管理和持久层框架。iBatis 是一个优秀的 SQL 映射框架,它允许开发者将 SQL 查询直接写入 XML 文件,从而与 Java 代码分离,提高可维护性和灵活性。而 Oracle...

    ibatis的sql-map dtd

    Ibatis,全称为MyBatis,是一个优秀的Java持久层框架,它主要负责SQL映射,使得开发者能够将SQL语句与Java代码分离,从而更好地管理数据库操作。在Ibatis中,`sql-map`和`sql-map-config`是两个重要的XML配置文件,...

    ibatis连接oracle所需的jar包

    下面我们将详细探讨这些关键的jar包以及它们在Ibatis与Oracle连接中的作用。 1. **ibatis-2.3.3.jar**: 这是Ibatis框架的核心库,包含了Ibatis的主要组件和API。它提供了SQL映射文件解析、事务管理、数据源配置等...

    ibatis 读取oracle clob类型

    ibatis 读取oracle clob类型

    ibatis调用oracle存储过程分页

    ibatis调用oracle存储过程分页

    maven spring struts ibatis oracle框架整合

    在IT行业中,构建大型企业级应用时,常常需要将多种技术框架进行整合,以实现高效、灵活和可维护的系统架构。"maven spring struts ibatis oracle框架整合"就是一个典型的例子,它涉及到四个关键的技术组件:Maven、...

    ibatis学习总结,oracle , 敏捷开发,

    在IT行业中,Ibatis、Oracle数据库以及敏捷开发是三个关键领域的知识,对于任何软件开发者,尤其是后端工程师来说,理解并掌握这些技能至关重要。本文将深入探讨这三个主题,旨在为你提供一个全面的学习概览。 首先...

    spring+ibatis+oracle分页缓存源码

    在Oracle中,我们可以利用ROWNUM伪列进行分页查询。例如,通过WHERE ROWNUM BETWEEN start AND end限制返回的结果集范围。同时,可以结合索引来进一步优化查询性能,尤其是在处理大数据量时。此外,Oracle的...

    ibatis实现结果集map封装(Demo下载)

    执行查询时,iBatis会自动将查询结果转换为Map对象。例如,如果你使用SqlSession的`selectOne`方法,可以这样获取结果: ```java Map, Object&gt; resultMap = sqlSession.selectOne("com.example.getUser", userId); ...

    ibatis调用oracle的函数,存储过程的方法

    本篇文章将详细介绍如何在Ibatis中调用Oracle的函数和存储过程。 首先,理解基本概念: 1. **Oracle函数**:函数是一段可重复使用的PL/SQL代码,它接收输入参数(IN参数),可选地返回一个结果值(RETURN参数)。...

    Ibatis调用Oracle存储过程返回自定义类型

    本文将深入探讨如何使用Ibatis框架来调用Oracle数据库中的存储过程,并实现返回自定义类型的处理方法。 #### Oracle自定义类型简介 Oracle支持用户自定义数据类型,这为复杂数据结构的应用提供了极大的便利。...

    ibatis + oracle 增删改查例子

    本示例“ibatis + oracle 增删改查例子”将向我们展示如何利用这两个工具进行基本的数据操作。 首先,`iBatis`的核心是SQL Map配置文件,它包含了SQL语句和映射规则。在`MyEclipse`中导入这个项目后,你需要找到并...

Global site tag (gtag.js) - Google Analytics