Spring Data JPA有没有使用方法名解析计算实体数量的方法?

189

Spring Data JPA支持使用规约来计算实体的数量。但是它是否有使用方法名称解析来计算实体数量的方法呢?比如说我想要一个名为countByName的方法,用于计算特定名称的实体数量,就像一个名为findByName的方法可以获取所有具有特定名称的实体一样。


7
请接受其中一个答案,YaoFeng。我已经测试了Spring Data JPA 1.5.2,并且像Abel所说的那样,countByName()语法是有效的。 - nullPainter
13个回答

342

Spring Data 1.7.1.RELEASE版本开始,你可以用两种不同的方式来实现,

  1. 新的方式,使用查询派生来实现计数和删除查询。阅读这里的第五个示例。
    public interface UserRepository extends CrudRepository<User, Integer> {
        long countByName(String name);
    }
  1. 旧的方式,使用@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);
}

也可以查看这个SO回答


3
其他聚合函数如求和、平均数怎么样? - lrkwz
1
问题是关于计数函数,而不是求和或平均值。Spring Data目前还不支持这些函数的“新方法”。您可以使用类似这个的东西。 - Georgios Syngouroglou
1
在你的第二和第三个示例中,我认为你需要使用"SELECT COUNT(u)...",因为这是一个计数查询。 - TheChrisPratt
谢谢您的评论。这是我的错误。 - Georgios Syngouroglou
不用担心,找到了 - commons-lang - NickJ
显示剩余2条评论

37
只要您不使用1.4版本,就可以使用显式注释: 示例:
@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);

5
请注意,该方法应返回long而不是int,否则您将收到一个ClassCastException异常,但没有任何线索。 - Rangi Lin

19

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));

1
我最喜欢这个版本 - 特别是因为我无法根据文档弄清楚它应该如何工作 :-) 你救了我的一天 :-) 顺便说一句:原始类型(例如 int)包含在示例搜索中,即使未设置 int age,也将被包括在内,但 Integer age 将从示例中排除(至少在 Eclipselink 中)。 - LeO
1
这正是我正在寻找的。谢谢! - emrekgn

13

工作示例

@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);
}

11

此功能已添加至版本 1.4 M1。


6
据Abel称,在1.4版本之后(在1.4.3.RELEASE版本中测试),可以使用以下方式: public long countByName(String name);

5

4
@Autowired
private UserRepository userRepository;

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

1
这个例子不是主题。用户询问如何按字段名计数,而不是如何从REST服务调用基本计数。 - Jad B.

4

非常感谢大家!现在它可以正常工作了。DATAJPA-231

如果能像find…By一样创建count…By…方法就太好了。例如:

public interface UserRepository extends JpaRepository<User, Long> {

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

1

现在已经实现了。 - Sergey Ponomarev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接