当前位置: 首页 > 面试题库 >

通过Java JDBC使用iBATIS的Oracle SQL DATE转换问题

叶福
2023-03-14
问题内容

我目前正在使用来自Java的iBATIS来解决Oracle SQL DATE转换问题。

我正在使用Oracle JDBC瘦驱动程序ojdbc14版本10.2.0.4.0。iBATIS版本2.3.2。Java 1.6.0_10-rc2-b32。

问题围绕着此SQL代码段返回的DATE类型的列:

SELECT *
FROM   TABLE(pk_invoice_qry.get_contract_rate(?,?,?,?,?,?,?,?,?,?)) order by from_date

包过程调用返回一个ref游标,该游标被包装在TABLE中,然后返回到易于读取的结果集,就像针对表的选择查询一样。

在PL / SQL Developer中,SQL DATE类型的返回列之一FROM_DATE具有一天中的时间精度:

Tue Dec 16 23:59:00 PST 2008

但是,当我通过iBATIS和JDBC访问此值时,该值仅保留当天的精度:

Tue Dec 16 12:00:00 AM PST 2008

这样显示时更清晰:

本来应该:

1229500740000 milliseconds since epoch
Tuesday, December 16, 2008 11:59:00 PM PST

但是得到这个代替:

1229414400000 milliseconds since epoch
Tuesday, December 16, 2008 12:00:00 AM PST
(as instance of class java.sql.Date)

无论我做什么,我都无法公开要通过Java JDBC和iBATIS返回的DATE列的全部精度。

iBATIS的映射是这样的:

FROM_DATE : 2008-12-03 : class java.sql.Date

当前的iBATIS映射是这样的:

<result property="from_date" jdbcType="DATE" javaType="java.sql.Date"/>

我也尝试过:

<result property="from_date" jdbcType="DATETIME" javaType="java.sql.Date"/>

要么

<result property="from_date" jdbcType="TIMESTAMP" javaType="java.sql.Timestamp"/>

但是所有尝试的映射都会产生相同的截断的Date值。好像JDBC在iBATIS尚未达到它之前就已经失去了失去数据精度的损害。

显然,我通过JDBC和iBATIS失去了一些数据精度,而当我留在PL / SQL
Developer中时,这并没有发生,因为它运行与测试脚本相同的SQL代码段。完全不能接受,非常令人沮丧,最终非常可怕。


问题答案:

完整的信息(而且比这里描述的要复杂得多,并且可能取决于所使用的Oracle驱动程序的特定版本)在Richard
Yee的答案中-[现在过期到Nabble的链接]

从小点心过期之前快速抢…

罗杰(Roger),请参阅:http :
//www.oracle.com/technetwork/database/enterprise-edition/jdbc-
faq-090281.html#08_01

具体来说:简单数据类型DATE和TIMESTAMP发生了什么?本节介绍简单数据类型。:-)

9.2之前的版本,Oracle JDBC驱动程序将DATE SQL类型映射到java.sql.Timestamp。这在一定程度上是有道理的,因为Oracle
DATE
SQL类型像java.sql.Timestamp一样包含日期和时间信息。到java.sql.Date的更明显映射有些问题,因为java.sql.Date不包含时间信息。在这种情况下,RDBMS不支持TIMESTAMP
SQL类型,因此将DATE映射到Timestamp也没有问题。

在9.2中,TIMESTAMP支持已添加到RDBMS。DATE和TIMESTAMP之间的区别在于TIMESTAMP包括纳秒,而DATE不包括。因此,从9.2开始,DATE映射到Date,而TIMESTAMP映射到Timestamp。不幸的是,如果您依赖于DATE值来包含时间信息,则会出现问题。

有几种方法可以解决此问题:

更改表以使用TIMESTAMP而不是DATE。这可能极少发生,但在可能的情况下是最佳解决方案。

更改您的应用程序以使用defineColumnType将列定义为TIMESTAMP而不是DATE。这样做有问题,因为除非您必须这样做,否则您真的不想使用defineColumnType(请参阅什么是defineColumnType以及何时应使用它?)。

更改您的应用程序以使用getTimestamp而不是getObject。如果可能的话,这是一个很好的解决方案,但是许多应用程序包含依赖于getObject的通用代码,因此并非总是可能的。

设置V8Compatible连接属性。这告诉JDBC驱动程序使用旧的映射而不是新的映射。您可以将此标志设置为连接属性或系统属性。您可以通过将连接属性添加到传递给DriverManager.getConnection的java.util.Properties对象或OracleDataSource.setConnectionProperties中来设置连接属性。您可以通过在Java命令行中包含-
D选项来设置系统属性。

java -Doracle.jdbc.V8Compatible =“ true” MyApp Oracle JDBC
11.1修复了此问题。从此版本开始,驱动程序默认将SQL
DATE列映射到java.sql.Timestamp。无需设置V8Compatible即可获取正确的映射。不推荐使用V8Compatible。您根本不应该使用它。如果您将其设置为true,则不会有任何伤害,但是您应该停止使用它。

尽管很少使用这种方式,但V8Compatible并不是要解决DATE to
Date问题,而是要支持与8i数据库的兼容性。8i(及更早的)数据库不支持TIMESTAMP类型。设置V8Compatible不仅导致从数据库中读取SQL
DATE时将其映射到Timestamp,而且还导致将所有Timestamps写入数据库时​​均转换为SQL DATE。由于不支持8i,因此11.1
JDBC驱动程序不支持此兼容模式。因此,不支持V8Compatible。

如上所述,从数据库读取时,默认情况下,11.1驱动程序会将SQL
DATE转换为时间戳。这始终是正确的做法,而9i的更改是一个错误。11.1驱动程序已还原为正确的行为。即使您没有在应用程序中设置V8Compatible,在大多数情况下也不会看到任何行为上的差异。如果使用getObject读取DATE列,则可能会发现差异。结果将是时间戳而不是日期。由于时间戳是Date的子类,因此这通常不是问题。您可能会注意到差异的地方是您是依靠从DATE到Date的转换来截断时间部分,还是对值进行toString。否则,更改应该是透明的。

如果由于某种原因您的应用程序对此更改非常敏感,而您仅必须具有9i-10g行为,则可以设置一个连接属性。将mapDateToTimestamp设置为false,驱动程序将还原为默认的9i-10g行为并将DATE映射为Date。

如果可能,应将列类型更改为TIMESTAMP而不是DATE。

-理查德

罗杰·沃斯(Roger Voss)写道:我在stackoverflow上发布了以下问题/问题,因此,如果有人知道解决方案,那么很高兴看到它在这里得到了回答:

通过Java JDBC使用iBATIS的Oracle SQL DATE转换问题

这是问题描述:

我目前正在使用来自Java的iBATIS来解决Oracle sql DATE转换问题。

我正在使用Oracle JDBC瘦驱动程序ojdbc14版本10.2.0.4.0。iBATIS版本2.3.2。Java 1.6.0_10-rc2-b32。

问题围绕着此SQL代码段返回的DATE类型的列:

SELECT * FROM TABLE(pk_invoice_qry.get_contract_rate(?,?,?,?,?,?,?,?,?,?

过程调用返回一个ref游标,该游标被包装在TABLE中,然后返回到易于读取的结果集,就像针对表的选择查询一样。

在PL / SQL Developer中,SQL DATE类型的返回列之一FROM_DATE具有一天中的时间精度:

Tue Dec 16 23:59:00 PST 2008

但是,当我通过iBATIS和JDBC访问此值时,该值仅保留当天的精度:

Tue Dec 16 12:00:00 AM PST 2008

这样显示时更清晰:

应为:自纪元以来的1229500740000毫秒,太平洋标准时间2008年12月16日,星期二11:59:00

但改为改为:自纪元以来的1229414400000毫秒(星期二)太平洋标准时间2008年12月16日12:00:00(作为类java.sql.Date的实例)

无论我做什么,我都无法公开要通过Java JDBC和iBATIS返回的DATE列的全部精度。

iBATIS的映射是这样的:

FROM_DATE:2008-12-03:类java.sql.Date

当前的iBATIS映射是这样的:

我也尝试过:

要么

但是所有尝试的映射都会产生相同的截断的Date值。好像JDBC在iBATIS甚至没有达到它之前就已经失去了丢失数据精度的损害。

显然,我通过JDBC和iBATIS失去了一些数据精度,而当我留在PL / SQL
Developer中运行与测试脚本相同的SQL代码段时,这并没有发生。完全不能接受,非常令人沮丧,最终非常可怕。



 类似资料:
  • 我正在尝试使用Kafka Connect的自定义转换器,但似乎无法正确使用。我希望有人有这方面的经验,能帮我弄清楚! > 我的自定义转换器的类路径是。 为了避免任何错误,我的自定义转换器目前只是预先存在的StringConverter的复制/粘贴(当然,当我开始工作时,这会改变)。https://github.com/apache/kafka/blob/trunk/connect/api/src/

  • null 出什么问题了?

  • 问题内容: 我有一堆高质量的PNG文件。我想使用PHP将它们转换为JPG,因为它的文件较小,同时又保持了质量。我想在网上显示JPG文件。 PHP是否具有执行此操作的功能/库?质量/压缩度好吗? 问题答案: 这样做可以将PNG安全地转换为白色透明的JPG。

  • 问题内容: 我正在寻找一种在Java App(使用JDBC)中打开Access MDB文件的方法。 快速的Google搜索建议我为此需要JDBC-ODBC Bridge。 这是否意味着我需要配置要在其上运行应用程序的每个系统,以便为要打开的MDB提供ODBC DSN? 还有一个问题(因为我以前从未使用过ODBC):通信是通过某种套接字(以客户机/服务器方式)还是通过方法/函数调用(例如嵌入Derb

  • 有人能帮助我为什么过渡没有得到应用吗? HTML 萨斯 我在这里有一个工作代码:https://codepen.io/loganlee/pen/rwnjpdz?editors=1100 我希望.box__faces-front和.box__faces-back的rotateY转换都要转换,并且我将转换放在父元素上,在本例中是.box__faces。 多谢了。

  • 问题内容: 我正在使用iBatis / Java和Postgres 8.3。当我在ibatis中插入时,我需要返回ID。 我使用下表描述我的问题:通过运行create语句自动生成 Sequence 。 目前,我使用以下sql映射: 看来这是检索新插入的id的ibatis方法。Ibatis首先运行INSERT语句,然后向序列询问最后一个ID。 我怀疑这是否可以与许多并发插入一起使用。 这会引起问题吗