在JPQL中可以选择EXISTS()吗?

Elk*_*Elk 18 jpa jpql java-ee jpa-2.0

我正在尝试运行一个查询,检查某些条件是否为真,并返回一个简单的布尔结果作为输出.让它有点棘手的是,其中一个条件是测试是否没有为一组标准返回结果.

我目前正在使用JPA-2.0和hibernate作为我的提供者,由MySQL支持.我已经得到一个在MySQL中运行良好的示例查询,但是当试图让它在JPQL中运行时,它会失败.MySQL查询看起来有点像这样:

Select exists(Select statement with criteria) 
  or not exists(Select statement with criteria);
Run Code Online (Sandbox Code Playgroud)

我也使用CASE获得了相同的输出,但由于JPQL不支持该语句.

无论如何,当我尝试在JPQL中使用类似的查询时,我得到错误:

"意外结束的子树"

根据我的理解,这意味着查询中缺少某些内容.有谁知道如何解决它?

Ren*_*ink 11

您可以使用案例表达式执行布尔查询.

从JPA 2.0(Java EE 6)开始,您可以创建TypedQuery.

String query = "select case when (count(*) > 0)  then true else false end from ......"
TypedQuery<Boolean> booleanQuery = entityManager.createQuery(query, Boolean.class);
boolean exists = booleanQuery.getSingleResult();
Run Code Online (Sandbox Code Playgroud)

在JPA 1.0(Java EE 5)中,您必须使用无类型查询.

Query booleanQuery = entityManager.createQuery(query);
boolean exists = (Boolean) booleanQuery.getSingleResult();
Run Code Online (Sandbox Code Playgroud)

  • 一种更易读的方法是:“select (count(*) &gt; 0) from ...” (2认同)
  • @Reda这仍然会搜索整个索引/表,尽管数据库可以并且应该在找到第一个结果后停止。 (2认同)

小智 8

在一个使用 Hibernate 5.2(支持 JPA 2.1)和 Spring Data Jpa 2.0.6 的项目中,我成功地使用了这个 JPQL 查询:

@Query("SELECT COUNT(c) > 0 FROM Contract c WHERE c.person.id = :pid")
Boolean existContractForPerson(@Param("pid") Long personId);
Run Code Online (Sandbox Code Playgroud)

在日志中,我读到生成的本机查询如下:

select count(contract0_.contract_id)>0 as col_0_0_ from contracts contract0_ where contract0_.fk_person_id=?
Run Code Online (Sandbox Code Playgroud)


Kow*_*ser 7

不,这是不可能的.

请参阅oracle 的JPQL BNF文档.

simple_cond_expression :: = comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression

exists_expression :: = [NOT] EXISTS(子查询)