我正在开发一个使用 JPA (Hibernate) 的项目,因此几乎所有查询都是用 JPQL 编写的。但对于查询,我需要深入了解特定的数据库类型,因此我编写了一个 native 查询。
该项目实际上是用 MySQL 和 Oracle DBMS 测试的。我的 native 查询是 "SELECT 1 FROM [...]"
;然后我需要知道结果是否存在(简单)以及它是否为 1(我猜你可以说这是多余的 :-))。
在这两种情况下,我都使用 createNativeQuery(String)
创建了一个 javax.persistence.Query
并且我像这样运行查询:Object r = q .getSingleResult();
(已经处理了异常)。
我发现在 MySQL 上 r 是一个 BigInteger
,而在 Oracle 中是 BigDecimal
类。
我对 JDBC 很感兴趣,有什么方法(更改查询、我正在使用的对象或方法调用)可以确保无论数据库系统如何,我的查询都将返回相同的数据类型被反对?这是可以配置的东西,取决于 jdbc,还是驱动程序特定的问题?
最佳答案
BigInteger
和BigDecimal
都是Number 的子类.因此,只需转换为公共(public)父类(super class)型并使用它的方法将其转换为原始类型,例如 int
。
Number r = (Number) q.getSingleResult();
boolean isOne = (r.intValue() == 1);
Hibernate 还有一个非常有用的 addScalar方法。看看Chapter 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 将尽最大努力将每个数据库列转换为它们各自的实体字段类型。不过,对于标量值来说,开销太大(我会选择第一个解决方案)。
关于java - 不同的数据库,不同的结果类型 'SELECT 1' 超过 jdbc : how to check the value?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21260273/