Spring Data JPA 有没有办法使用方法名称解析来计算实体?

Posted

技术标签:

【中文标题】Spring Data JPA 有没有办法使用方法名称解析来计算实体?【英文标题】:Does Spring Data JPA have any way to count entites using method name resolving? 【发布时间】:2012-05-28 14:48:27 【问题描述】:

Spring Data JPA 支持使用规范计数实体。但是它有没有办法使用方法名称解析来计算实体?假设我想要一个方法 countByName 来计算具有特定名称的实体,就像方法 findByName 来获取具有特定名称的所有实体一样。

【问题讨论】:

姚峰,请接受其中一个答案。我已经测试过 Spring Data JPA 1.5.2,countByName() 语法就像 Abel 笔记一样工作。 【参考方案1】:

我只使用了几个星期,但我不认为这是绝对可行的,但是您应该能够通过更多的努力获得相同的效果;只需自己编写查询并注释方法名称即可。它可能并不比自己编写方法简单得多,但在我看来它更干净。

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

【讨论】:

【参考方案2】:

根据问题DATAJPA-231,该功能尚未实现。

【讨论】:

现在实现了【参考方案3】:

此功能已在 1.4 M1 版本中添加

【讨论】:

【参考方案4】:

显然现在已经实现了DATAJPA-231

【讨论】:

【参考方案5】:

只要不使用1.4版本,都可以使用显式注解:

示例:

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

【讨论】:

注意该方法应该返回long而不是int,否则你会得到一个没有任何线索的ClassCastException【参考方案6】:

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

public long countByName(String name);

【讨论】:

【参考方案7】:

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

    新方法,对计数和删除查询使用查询派生。阅读this,(示例5)。 例如,
    public interface UserRepository extends CrudRepository<User, Integer> 
        long countByName(String name);
    
    老办法,使用@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);

还要检查this so answer。

【讨论】:

sum、average 等其他聚合函数呢? 问题是关于计数函数,而不是求和或平均值。 Spring data 尚不支持此功能的“新方式”。你可以使用类似this 在您的第二个和第三个示例中,我认为您需要使用“SELECT COUNT(u)...”,因为这应该是一个计数查询。 感谢您的评论。这是我的错。 不用担心,找到了 - commons-lang【参考方案8】:

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

如果可以创建 count...By... 方法,就像 find...By 个,那就太好了。示例:

public interface UserRepository extends JpaRepository<User, Long> 

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

【讨论】:

【参考方案9】:

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

【讨论】:

这个版本我最喜欢 - 特别是因为我不知道这应该如何根据文档工作:-) 你拯救了我的一天 :-) 作为备注:Primitives (eg int)被包含在 expamle-search 中,即 int age 将被包含,尽管未设置,但 Integer age 将从示例中排除(至少在 Eclipselink 中) 这正是我想要的。谢谢!【参考方案10】:

工作示例

@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】:
@Autowired
private UserRepository userRepository;

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

【讨论】:

这个例子跑题了。用户询问如何按字段名称计数,而不是如何从 REST 服务调用基本计数。【参考方案12】:

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

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

【讨论】:

以上是关于Spring Data JPA 有没有办法使用方法名称解析来计算实体?的主要内容,如果未能解决你的问题,请参考以下文章

如何记录 Spring Data JPA 存储库方法执行时间?

Spring Data JPA:使用连接表进行排序和分页

如何使用 Spring Data JPA(Hibernate) 跨映射表过滤关联实体?

Spring data jpa JavassistLazyInitializer 不仅是Json序列化问题.以及解决办法

没有 Spring Boot 的 Spring Data JPA

Spring Data JPA 多个实体类表联合视图查询