Java 使用Hibernate避免使用Oracle进行从日期到时间戳的隐式转换
我使用Hibernate 3.2.7.GA标准查询从Oracle Enterprise Edition 10.2.0.4.0数据库中选择行,并通过时间戳字段进行过滤。该字段在java中的类型为Java 使用Hibernate避免使用Oracle进行从日期到时间戳的隐式转换,java,oracle,hibernate,Java,Oracle,Hibernate,我使用Hibernate 3.2.7.GA标准查询从Oracle Enterprise Edition 10.2.0.4.0数据库中选择行,并通过时间戳字段进行过滤。该字段在java中的类型为java.util.Date,在Oracle中的类型为Date 字段映射到java.sql.Timestamp,Oracle将所有行转换为Timestamp,然后与传入的值进行比较,从而破坏性能 一种解决方案是使用Hibernate的sqlRestriction()和Oracle的to_DATE函数。这将修
java.util.Date
,在Oracle中的类型为Date
字段映射到java.sql.Timestamp
,Oracle将所有行转换为Timestamp
,然后与传入的值进行比较,从而破坏性能
一种解决方案是使用Hibernate的sqlRestriction()
和Oracle的to_DATE
函数。这将修复性能,但需要重写应用程序代码(大量查询)
那么有没有更优雅的解决方案?既然Hibernate已经进行了类型映射,那么是否可以将其配置为执行正确的操作
更新:问题出现在各种配置中,但这里有一个具体示例:
- Oracle企业版10.2.0.4.0
- Oracle JDBC驱动程序11.1.0.7.0
- Hibernate 3.2.7.GA
- Hibernate的Oracle10g方言
- Java 1.6.0_16
- 列类型可以通过以下方式更改: 一个简单的“altertablename”修改 columnName时间戳(precisionVal)”
- 我惊讶地发现这一点
这些列上的内容不必是
重建
同样,这只有在您致力于Hibernate时才有意义。这听起来可能很激烈,但当遇到这个问题时,我们最终将数据库中的所有日期列转换为时间戳类型。我看不出这有什么缺点,如果Hibernate是您的主要应用程序平台,那么您将避免将来的麻烦 注:
- 列类型可以通过以下方式更改: 一个简单的“altertablename”修改 columnName时间戳(precisionVal)”
- 我惊讶地发现这一点
这些列上的内容不必是
重建
DATE
列的实际值将转换为java.sql.Timestamp
,而不是将带有java.util.DATE
的绑定变量转换为java.sql.Timestamp
解释计划
输出将有助于识别问题。此外,Oracle跟踪可以准确地告诉您在查询中为bind变量分配了什么类型
如果这种情况真的发生,那可能是甲骨文的错误
您可以通过以下方式解决此问题:
- 在
列上创建一个FBI(),将其转换为日期
。例如:时间戳
CREATE INDEX tab_idx ON tab (CAST(date_col AS TIMESTAMP)) COMPUTE STATISTICS;
- 创建包含相同
表达式的视图。如果需要,可以保留相同的列名:CAST
CREATE VIEW v AS SELECT CAST(date_col AS TIMESTAMP) AS date_col, col_1, ... FROM tab;
- 使用视图而不是表(这通常是一个好主意,例如,如果您已经在使用视图,则根本不需要更改代码)。当
变量将在java.sql.Timestamp
条件下与WHERE
一起使用时,(如果选择足够多),将使用索引date\u col
- 如果您发现了为什么会出现
(或者Oracle修复了潜在的bug),您可以随时返回,只需更改视图(并删除FBI),它对代码是完全透明的java.sql.Timestamp
DATE
列的实际值将转换为java.sql.Timestamp
,而不是将带有java.util.DATE
的绑定变量转换为java.sql.Timestamp
解释计划
输出将有助于识别问题。此外,Oracle跟踪可以准确地告诉您在查询中为bind变量分配了什么类型
如果这种情况真的发生,那可能是甲骨文的错误
您可以通过以下方式解决此问题:
- 在
列上创建一个FBI(),将其转换为日期
。例如:时间戳
CREATE INDEX tab_idx ON tab (CAST(date_col AS TIMESTAMP)) COMPUTE STATISTICS;
- 创建包含相同
表达式的视图。如果需要,可以保留相同的列名:CAST
CREATE VIEW v AS SELECT CAST(date_col AS TIMESTAMP) AS date_col, col_1, ... FROM tab;
- 使用视图而不是表(这通常是一个好主意,例如,如果您已经在使用视图,则根本不需要更改代码)。当
变量将在java.sql.Timestamp
条件下与WHERE
一起使用时,(如果选择足够多),将使用索引date\u col
- 如果您发现了为什么会出现
(或者Oracle修复了潜在的bug),您可以随时返回,只需更改视图(并删除FBI),它对代码是完全透明的java.sql.Timestamp