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()
的返回类型与字段类型一致。比如这里 age
是 int
,所以返回的也是 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()
的返回类型根据字段类型不同会返回 Long
或 Double
。
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 获取。