如何正确判断"存在"JPA Criteria Query子句是返回true还是false?

Edy*_*rne 10 java hibernate jpa criteria-api

我不知道如何执行返回布尔输出的JPA条件查询.

目标是在Oracle上呈现时具有看起来像这样的条件查询:

select 1 from dual where exists ( ... );
Run Code Online (Sandbox Code Playgroud)

where exists (...)我用子查询执行的部分.我正在努力解决外部问题.

这样做的实际用途是确定exists子句中的子查询是返回true还是false.

这就是我写的:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery<Object> query = criteriaBuilder.createQuery();
query.from(Boolean.class);
query.select(criteriaBuilder.literal(true));

Subquery<Location> subquery = query.subquery(Location.class);
Root<Location> subRootEntity = subquery.from(Location.class);
subquery.select(subRootEntity);

Path<?> attributePath = subRootEntity.get("State");
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX"));
subquery.where(predicate);
query.where(criteriaBuilder.exists(subquery));

TypedQuery<Object> typedQuery = em.createQuery(query);
Run Code Online (Sandbox Code Playgroud)


最后一行输出错误,指出" 布尔值不是实体 ".我认为我的问题是不知道如何表达查询的" from "部分,以便结果输出1或0/true或false - 而不是实体.

我知道我可以检索任何实体,然后检查结果列表的大小是否为1.

我问如何得到一个布尔结果,既避免了检索这些列的不必要的任务,也学习了如何做到这一点.

这有可能吗?

谢谢!爱德华多

Mat*_*ler 11

是的,这是可能的.假设您有一个与您的dual表对应的实体,您将需要使用该实体类CriteriaQuery#from.

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery<Boolean> query = criteriaBuilder.createQuery(Boolean.class);
query.from(dual.class);
query.select(criteriaBuilder.literal(true));

Subquery<Location> subquery = query.subquery(Location.class);
Root<Location> subRootEntity = subquery.from(Location.class);
subquery.select(subRootEntity);

Path<?> attributePath = subRootEntity.get("State");
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX"));
subquery.where(predicate);
query.where(criteriaBuilder.exists(subquery));

TypedQuery<Boolean> typedQuery = em.createQuery(query);
Run Code Online (Sandbox Code Playgroud)


小智 8

Hibernate 5 正在运行:

Subquery<Integer> subquery = query.subquery(Integer.class);
Root<Location> subRootEntity = subquery.from(Location.class);
subquery.select(criteriaBuilder.literal(1));

Path<?> attributePath = subRootEntity.get("State");
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX"));
subquery.where(predicate);
query.where(criteriaBuilder.exists(subquery));
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以为一个属性(例如ID)执行选择,并将返回的最大结果设置为1,以确保数据库不会执行超出必要的工作(如计算所有实例).然后您的结果列表将为空(exists = false)或具有一个元素(exists = true).