Spring Data JPA和Exists查询

Ste*_*erl 46 java hibernate jpa jpql spring-data

我正在使用Spring Data JPA(Hibernate作为我的JPA提供程序)并且想要定义exists附加了HQL查询的方法:

public interface MyEntityRepository extends CrudRepository<MyEntity, String> {

  @Query("select count(e) from MyEntity e where ...")
  public boolean existsIfBlaBla(@Param("id") String id);

}
Run Code Online (Sandbox Code Playgroud)

当我运行此查询时,我得到了一个java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Boolean.

HQL查询如何使其工作?我知道我可以简单地返回一个Long值,然后检查我的Java代码是否count > 0,但是这个解决方法不应该是必要的,对吧?

Ank*_*oni 138

Spring Data JPA 1.11现在支持exists存储库查询派生中的投影.

见文档这里.

在您的情况下,以下将起作用:

public interface MyEntityRepository extends CrudRepository<MyEntity, String> {  
    boolean existsByFoo(String foo);
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是Spring数据的重点 - 您不必编写任何HQL :) (7认同)
  • 如果您要添加一个工作示例,我将很乐意提供支持. (4认同)
  • 是的,但如果你想检查一个字段上是否有值的记录 - 这绝对是简单的用例:)但是对于更复杂的,我同意 - 弹簧数据有时效率不高. (2认同)

K. *_*ddy 59

我认为您可以简单地更改查询以返回布尔值

@Query("select count(e)>0 from MyEntity e where ...")
Run Code Online (Sandbox Code Playgroud)

PS:如果你检查存在基于主键值CrudRepository已经有exists(id)方法.

  • `count(e)> e`可能只适用于某些数据库(例如Oracle).使用DB2时它不会,并且当count(e)> 0时你将不得不使用`select case然后从实体e中使用其他false结尾 (15认同)
  • 在此处执行 SQL 存在查询而不是计数行。使用 count 必须完成索引中的所有行(希望如此)或者没有索引的表扫描。SQL 存在将在遇到的第一行之后返回,而不是查找每一行并像 count(*) 那样计算它们。在一个 10 行的表中,这在 10s/100s 中没有问题,而且更重要。 (2认同)

Run*_*omu 9

在我的情况下,它没有像下面那样工作

@Query("select count(e)>0 from MyEntity e where ...")
Run Code Online (Sandbox Code Playgroud)

您可以将其作为布尔值返回,如下所示

@Query(value = "SELECT CASE  WHEN count(pl)> 0 THEN true ELSE false END FROM PostboxLabel pl ...")
Run Code Online (Sandbox Code Playgroud)


Ste*_*e L 8

从Spring数据1.12开始,您可以通过扩展QueryByExampleExecutor接口(JpaRepository已经扩展它)来使用示例functionnality的查询.
然后你可以使用这个查询(以及其他):

<S extends T> boolean exists(Example<S> example);
Run Code Online (Sandbox Code Playgroud)

考虑一个实体MyEntity作为属性name,您想知道具有该名称的实体是否存在,忽略大小写,那么对此方法的调用可能如下所示:

//The ExampleMatcher is immutable and can be static I think
ExampleMatcher NAME_MATCHER = ExampleMatcher.matching()
            .withMatcher("name", GenericPropertyMatchers.ignoreCase());
Example<MyEntity> example = Example.<MyEntity>of(new MyEntity("example name"), NAME_MATCHER);
boolean exists = myEntityRepository.exists(example);
Run Code Online (Sandbox Code Playgroud)


Spi*_*der 8

这几天轻松了很多!

@Repository
public interface PageRepository extends JpaRepository<Page, UUID> {

    Boolean existsByName(String name); //Checks if there are any records by name
    Boolean existsBy(); // Checks if there are any records whatsoever

}
Run Code Online (Sandbox Code Playgroud)