SpringData JPA使用聚合函数返回结果如何接收

本文介绍了如何在SpringBoot中使用JPA进行复杂查询,特别是当查询结果不直接映射到实体类时的处理方法。通过创建一个包装类`DomainVo`,并利用`@Query`注解配合构造方法实现字段映射,成功实现了对`Urls`表的统计查询,得到每个域名及其出现次数。测试结果显示查询功能正常工作。
摘要由CSDN通过智能技术生成

1、需求

我的需求是统计域名以及域名出现的次数。
在这里插入图片描述
之前使用springboot jpa都是把数据库中的表跟实体类绑定,创建继承JpaRepository的接口。如下:

@Repository
public interface UrlsRepository extends JpaRepository<Urls, String> {
 
    Optional<Urls> findById(Integer id);
}

但是对于这种查询却无法绑定到原有的实体类。那么改怎么解决这种需求呢?

2、解决方法

用一个包装类来接收查询结果,根据类的构造方法实现字段映射

@Getter
@Setter
@ToString
public class DomainVo {
    private String domain;
    private Long visitCount;
 
    public DomainVo(String domain, Long visitCount) {
        this.domain = domain;
        this.visitCount = visitCount;
    }
}

repository写法

    /*
    注意:
    1、使用的是全类名
    2、查询的表对应的是已经绑定的实体类Urls
    3、nativeQuery设为false,表示使用的是jpql语言。
     */ 
	@Query(value = "SELECT new com.ununie.chromehistory.model.vo.DomainVo(u.domain,sum(u.visitCount)) from Urls u GROUP BY u.domain ORDER BY sum(u.visitCount) desc")
    List<DomainVo> findDomainCount();

测试:

    @Test
    public void findDomainCount() {
        List<DomainVo> domainCount = urlsRepository.findDomainCount();
        for (DomainVo vo : domainCount) {
            System.out.println(vo);
        }
    }
### JPA 实现分组查询 在 Java Persistence API (JPA) 中,`GROUP BY` 子句用于按一个或多个列对结果集进行分组。这通常与聚合函数一起使用来执行汇总操作。 #### 使用 JPQL 进行分组查询 下面是一个简单的例子,展示了如何通过 JPQL 执行带有 `GROUP BY` 和 `HAVING` 的查询: ```java // 假设有一个实体类 CourseRegistration 表示课程注册记录, // 并且想要统计每门课有多少学生选修,并只返回超过一定数量学生的课程。 String jpql = "SELECT cr.course.name, COUNT(cr.student.id)" + "FROM CourseRegistration cr" + "GROUP BY cr.course.name" + "HAVING COUNT(cr.student.id) > :minStudents"; TypedQuery<Object[]> query = entityManager.createQuery(jql, Object[].class); query.setParameter("minStudents", minimumStudentCount); // 设置参数值 List<Object[]> results = query.getResultList(); for (Object[] result : results) { System.out.println("Course Name: " + result[0]); System.out.println("Number of Students Enrolled: " + result[1]); } ``` 此代码片段创建了一个 JPQL 查询语句[^1],它选择了课程名称以及该课程的学生人数作为两个字段的结果列表项;接着设置了最小学生数条件并通过 HAVING 来过滤掉不符合条件的数据集合。 #### 结合 Spring Data JPA 库简化开发工作量 当项目基于Spring框架构建时,推荐利用Spring Data JPA所提供的特性进一步减少样板代码编写的工作负担。定义自定义方法签名即可轻松完成复杂的业务逻辑需求而无需手写完整的JPQL表达式: ```java public interface CourseRegistrationRepository extends JpaRepository<CourseRegistration, Long>, JpaSpecificationExecutor<CourseRegistration> { @Query(value="select new map(c as courseName, count(s) as studentCount)" +"from CourseRegistration r join r.course c join r.student s" +"group by c having count(s)>?1") List<Map<String,Object>> findCoursesWithMoreThanXStudents(int minNumberOfStudents); } ``` 上述接口声明了名为 `findCoursesWithMoreThanXStudents()` 方法,其内部实现了相同的功能但是更加简洁明了[^2]。这里还引入了构造器表达式的概念(`new map`)用来直接映射查询结果Java对象属性上以便于后续处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值