【问题标题】:How to detect Database from Hibernate user type?如何从 Hibernate 用户类型中检测数据库?
【发布时间】:2012-10-04 11:36:58
【问题描述】:

有没有办法从用户类型确定正在使用的数据库?我的用户类型需要根据数据库(无论是 HSQL 还是 Oracle)将不同的对象传递给preparedStatement.setObject。我打算使用preparedStatement中的DataBaseMetaData作为

preparedStatement.getConnection().getMetaData().getDatabaseProductName()

但我不确定是否有一组明确定义的字符串,我可以将其与上述字符串进行比较以确定数据库。

我要解决的更大问题是,我们在 Oracle 中使用 DATE 列,而 hibernate 将 JodaDateTime 映射到 TIMESTAMP(这是唯一可以保存日期和时间的类型)。因此,Oracle 在执行日期比较之前将数据库中的 DATE 值提升为时间戳。这会导致性能下降,因为会跳过数据库索引。排除了将列类型从 DATE 更改为 TIMESTAMP 的选项,因为它需要更多空间,并且我们的应用程序不需要超过秒的精度。因此,我计划编写一个将 DateTime 转换为 oracle.sql.DATE 的 userType 并在preparedStatement 中设置参数,以便没有索引不匹配。 (如下图sn-p):

    public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
    if (value == null) {
        Hibernate.TIMESTAMP.nullSafeSet(preparedStatement, null, index);
    } else {
        preparedStatement.setObject(index, new oracle.sql.DATE(new Timestamp(((DateTime) value).getMillis())), Types.DATE);
    }
}

上述方法的问题在于,如果我使用不同的数据库进行单元测试(HSQLDB),它将无法工作,因为 HSQLDialect 不理解“oracle.sql.DATE”。这是我需要从 userType 了解数据库并在preparedStatement 中设置不同对象的地方。

所以,我想知道

  • 如果有更好的方法来解决 DATE-TIMESTAMP 不匹配问题
  • 如果不是,如何从用户类型中正确识别 DB。

谢谢。

【问题讨论】:

  • 有一种替代方法可以将应用程序代码更改为将 sql 参数绑定为字符串。
  • 有一种替代方法可以更改应用程序代码和查询,以将 sql 参数绑定为字符串。这不是 sql 中的 dateColumnName >= :date (其中参数绑定为时间戳),我们可以使用 dateColumnName >= to_date(:date,'yyyymmddhh24miss') (其中参数绑定为字符串)。但是我不想修改我的应用程序代码,所以这个替代方案是不可行的。
  • 我还尝试将用户类型更改为 - String strVal = "to_date('" + TIMESTAMP_TO_DATE_FORMAT.print(dateTime.getMillis()) + '",'YYYYMMDDHH24MISS') "; preparedStatement.setString(index,strVal); 。但我得到了错误 - "java.sql.SQLDataException: data exception: invalid datetime format" at org.hsqldb.jdbc.Util.sqlException(Unknown Source)

标签: java oracle hibernate hsqldb


【解决方案1】:

使用Dialect.getDialect() 检索您当前的方言。检查实例类型以了解数据库。例如:

       Dialect dialect= Dialect.getDialect();
       //<-- compare against the expected dailect classes
       if(dialect instanceof OracleDialect){  
           //your database is oracle
       }else if(dialect instanceof HSQLDialect){
        //<-- compare against the expected dailect classes
           //your database is HSQL
       }

我不太确定您的目标,但以上内容应该对您有所帮助。

【讨论】:

  • 获取方言确实解决了我的问题,但我必须从会话工厂获取方言。 Dialect.getDialect() 仅在系统属性中可用时才返回方言。
猜你喜欢
  • 2012-04-12
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 2011-01-07
相关资源
最近更新 更多