1. 概述

Hibernate 的聚合函数(Aggregate Functions)用于对满足查询条件的所有实体属性值进行计算并返回最终结果

Hibernate Query Language(HQL)支持多种聚合函数,包括 min()max()sum()avg()count(),这些函数可以在 SELECT 语句中使用。和其他 SQL 关键字一样,这些函数的使用是大小写不敏感的。

在本教程中,我们将通过示例展示如何在 HQL 中使用这些聚合函数。需要注意的是,示例中我们使用了基本类型或包装类型来接收聚合函数的结果。HQL 对这两种方式都支持,可以根据需要选择。

2. 初始配置

我们先定义一个 Student 实体类:

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long studentId;

    private String name;

    private int age;

    // constructor, getters and setters
}

然后初始化一些测试数据:

public class AggregateFunctionsIntegrationTest {

    private static Session session;
    private static Transaction transaction;

    @BeforeClass
    public static final void setup() throws HibernateException, IOException {
        session = HibernateUtil.getSessionFactory()
            .openSession();
        transaction = session.beginTransaction();

        Student jonas = new Student("Jonas", 22);
        session.save(jonas);

        Student sally = new Student("Sally", 20);
        session.save(sally);

        Student simon = new Student("Simon", 25);
        session.save(simon);

        Student raven = new Student("Raven", 21);
        session.save(raven);

        Student sam = new Student("Sam", 23);
        session.save(sam);
    }
}

注意:studentId 字段使用了 SEQUENCE 策略生成主键。如果你对 Hibernate 主键生成策略感兴趣,可以参考 Hibernate Identifier Generation Strategies

3. min()

假设我们要找出所有学生中年龄最小的那个,可以使用 min() 函数:

@Test
public void whenMinAge_ThenReturnValue() {
    int minAge = (int) session.createQuery("SELECT min(age) from Student")
      .getSingleResult();
    assertThat(minAge).isEqualTo(20);
}

踩坑提醒getSingleResult() 返回的是 Object 类型,需要根据实际类型进行强转。

4. max()

类似地,max() 函数用于获取最大值:

@Test
public void whenMaxAge_ThenReturnValue() {
    int maxAge = (int) session.createQuery("SELECT max(age) from Student")
      .getSingleResult();
    assertThat(maxAge).isEqualTo(25);
}

⚠️ 注意min()max() 的返回类型与字段类型一致。比如这里 ageint,所以返回的也是 int

5. sum()

使用 sum() 可以计算所有学生年龄的总和:

@Test
public void whenSumOfAllAges_ThenReturnValue() {
    Long sumOfAllAges = (Long) session.createQuery("SELECT sum(age) from Student")
      .getSingleResult();
    assertThat(sumOfAllAges).isEqualTo(111);
}

注意sum() 的返回类型根据字段类型不同会返回 LongDouble

6. avg()

计算平均年龄,可以使用 avg() 函数:

@Test
public void whenAverageAge_ThenReturnValue() {
    Double avgAge = (Double) session.createQuery("SELECT avg(age) from Student")
      .getSingleResult();
    assertThat(avgAge).isEqualTo(22.2);
}

注意:无论字段类型是什么,avg() 函数始终返回 Double 类型。

7. count()

和原生 SQL 一样,HQL 也支持 count() 函数。我们可以用来统计学生总数:

@Test
public void whenCountAll_ThenReturnValue() {
    Long totalStudents = (Long) session.createQuery("SELECT count(*) from Student")
      .getSingleResult();
    assertThat(totalStudents).isEqualTo(5);
}

注意count() 函数始终返回 Long 类型。

此外,count() 支持以下几种变体:

  • count(*)
  • count(property)
  • count(distinct property)
  • count(all property)

这些都和原生 SQL 的语义一致。

8. 总结

本教程简要介绍了 Hibernate 中常用的聚合函数。它们的使用方式与 SQL 中的聚合函数基本一致。

这些函数在日常开发中非常实用,尤其是在需要进行统计分析时。

🔗 完整代码可从 GitHub 获取。


原始标题:Hibernate Aggregate Functions