Spring Data JPA是否可以使用方法名称解析来计数实体?


125

Spring Data JPA支持使用规范对实体进行计数。但是,它有什么方法可以使用方法名称解析来计数实体?假设我要一种方法countByName来计算具有特定名称的实体,就像findByName获取具有特定名称的所有实体的方法一样。


6
请接受答案之一,姚峰。我已经测试了Spring Data JPA 1.5.2,countByName()语法可以用作Abel注释。
nullPainter 2014年

Answers:


214

Spring Data 1.7.1.RELEASE开始,您可以通过两种不同的方式来实现,

1)新方法,对计数和删除查询都使用查询派生。阅读此内容(示例5)。例,

public interface UserRepository extends CrudRepository<User, Integer> {
    Long countByName(String name);
}

2)旧方法,使用@Query注释。
例,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=?1")
    Long aMethodNameOrSomething(String name);
}

或也使用@Param注释,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=:name")
    Long aMethodNameOrSomething(@Param("name") String name);
}

也检查这个答案


3
其他合计函数,例如求和,平均值呢?
lrkwz 2015年

问题是关于计数函数,而不是总和或平均值。Spring数据尚不支持此功能的“新方法”之类的功能。您可以使用类似这样的
George Siggouroglou,2015年

1
在您的第二个和第三个示例中,我认为您将需要使用“ SELECT COUNT(u)...”,因为这应该是一个计数查询。
TheChrisPratt 2015年

感谢您的评论。是我的错
乔治·西格古罗格

不要着急,发现它-commons-lang
NickJ 17-2-28

19

只要您不使用1.4版本,就可以使用显式注释:

例:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);

3
请注意,该方法应返回long而不是int,否则您将获得ClassCastException而没有任何线索
Rangi Lin 2014年

13

JpaRepository还扩展了QueryByExampleExecutor。因此,您甚至不需要在界面上定义自定义方法:

public interface UserRepository extends JpaRepository<User, Long> {
    // no need of custom method
}

然后查询如下:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));

这个版本是我最喜欢的版本-尤其是因为我不知道如何根据文档进行提示:-)您节省了时间:-)谨此说明:expamle-search中包含基元(例如int),即int age将被包括虽然没有设置,但Integer age将被从所述样品(至少在的EclipseLink)排除
LEO

这正是我想要的。谢谢!
emrekgn


8

工作实例

@Repository
public interface TenantRepository extends JpaRepository< Tenant, Long > {
    List<Tenant>findByTenantName(String tenantName,Pageable pageRequest);
    long countByTenantName(String tenantName);
}

从DAO层调用

@Override
public long countByTenantName(String tenantName) {
    return repository.countByTenantName(tenantName);
}

5

根据Abel的说法,在1.4版本(在1.4.3.RELEASE版本中进行测试)之后,可以这样做:

public long countByName(String name);



2

谢谢大家!现在工作了。DATAJPA-231

如果可以创建count ... By ...方法,就像find ... By那样,那将是很好的。例:

public interface UserRepository extends JpaRepository<User, Long> {

   public Long /*or BigInteger */ countByActiveTrue();
}


1

我只使用了几个星期,但我不认为这是完全可能的,但是您应该可以多花一点功夫就能达到相同的效果。只需自己编写查询并注释方法名称即可。它可能比自己编写方法简单得多,但在我看来,它更干净。

编辑:现在可以根据DATAJPA-231


0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}

1
这个例子不合时宜。用户询问如何通过字段名进行计数,而不是如何从REST服务中调用基本计数。
Jad B.

0

如果有人想基于多个条件获取计数,那么这里是一个示例自定义查询

@Query("select count(sl) from SlUrl sl where sl.user =?1 And sl.creationDate between ?2 And ?3")
    long countUrlsBetweenDates(User user, Date date1, Date date2);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.