2012-10-14 36 views
2

有没有一种确定性地确定用户类型中正在使用的数据库的方法?我的用户类型需要根据数据库(不管是HSQL还是Oracle)将不同的对象传递给preparedStatement.setObject。我正打算使用的DatabaseMetaData从preparedStatement时为如何从Hibernate用户类型中检测数据库?

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

,但我不知道是否有一个良好定义的一组字符串,我可以比较上面来确定数据库的。

我试图解决的一个更大的问题是,我们在Oracle中使用DATE列,而hibernate将JodaDateTime映射到TIMESTAMP(这是唯一可以保存日期和时间的类型)。因此,Oracle在执行日期比较之前将DB中的DATE值提升为时间戳。这会导致性能较差,因为数据库索引被跳过。将列类型从DATE更改为TIMESTAMP的选项已被排除,因为它需要更多空间,我们的应用程序不需要超过秒的精度。因此,我打算编写一个将DateTime转换为oracle.sql.DATE的userType,并在prepareStatement中设置参数,以避免索引不匹配。 (代码片段如下图所示):

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。日期”。这是我需要从userType知道数据库并在preparedStatement中设置不同的对象的地方。

所以,我想知道

  • 如果解决DATE时间戳不匹配的问题
  • 如果没有,如何从用户类型正确识别DB一种更好的方式。

谢谢。

+0

还有一种方法可以更改应用程序代码,以便将sql参数绑定为字符串。 –

+0

还有一种替代方法来更改应用程序代码并查询大意为sql参数绑定为字符串。我们可以使用dateColumnName> = to_date(:date,'yyyymmddhh24miss')(其中参数绑定为字符串),而不是dateColumnName> =:date(其中参数绑定为时间戳)。但我不想修改我的应用程序代码,因此这种替代方法不可行。 –

+0

我也尝试将用户类型更改为 - 'String strVal =“to_date(''+ TIMESTAMP_TO_DATE_FORMAT.print(dateTime.getMillis())+'','YYYYMMDDHH24MISS')”; preparedStatement.setString(index,strVal);'。但我得到的错误 - “”java.sql.SQLDataException:数据异常:无效的日期时间格式“在org.hsqldb.jdbc.Util.sqlException(未知源)' –

回答

3

使用Dialect.getDialect()检索您当前的方言。检查实例类型知道下面的数据库.e.g:

 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 
     } 

我不是很确定你的职业目标,但是上面应该帮助你。

+2

获取方言确实解决了我的问题,但我有从会话工厂获得方言。 'Dialect.getDialect()'只有在系统属性中可用时才返回方言。 –

相关问题