2

我正在开发一个使用 JPA (Hibernate) 的项目,所以几乎所有的查询都是用 JPQL 编写的。但是对于查询,我需要深入了解特定的数据库类型,所以我编写了一个本机查询。

该项目实际上是用 MySQL 和 Oracle DBMS 测试的。我的本机查询是"SELECT 1 FROM [...]"; 然后我需要知道结果是否存在(简单)以及是否为 1(我猜你可能会说这是多余的 :-))。

在这两种情况下,我都在创建一个javax.persistence.QuerywithcreateNativeQuery(String)并像这样运行查询:(Object r = q.getSingleResult();已经处理了异常)。
我发现在 MySQL r 上是 a BigInteger,而在 Oracle 上是 class BigDecimal

我对 JDBC 很感兴趣,有什么方法(更改我正在使用的查询、对象或方法调用)我可以确保无论数据库系统运行什么,我的查询都将返回相同的数据类型? 这是可以配置的东西,取决于 jdbc,还是驱动程序特定的问题?

4

1 回答 1

1

BigInteger和都是NumberBigDecimal的子类。因此,只需转换为通用超类型并使用它的方法将其转换为原始类型,例如.int

Number r = (Number) q.getSingleResult();
boolean isOne = (r.intValue() == 1);

Hibernate 还有一个非常有用的addScalar方法。查看其文档的第 18 章以获取更多信息。

如果您决定使用此解决方案,请记住这意味着打开您的 JPA 层并使用供应商特定的 API:

Session session = entityManager.unwrap(Session.class);
Integer r = (Integer) session.createSQLQuery("SELECT 1 AS one FROM [...]")
   .addScalar("one", IntegerType.INSTANCE)
   .uniqueResult();

最后,JPA 有自己的SqlResultSetMapping注解。有了它,您可以将本机结果包装在一个实体中。JPA Providers 将尽最大努力将每个数据库列转换为它们各自的实体字段类型。不过,对于标量值,开销太大(我会选择第一个解决方案)。

于 2014-01-21T14:20:51.083 回答