Hibernate 的 batch fetching 是一个懒加载时的优化策略,和“你主动查多少条”不同,它是在你触发懒加载时,自动在背后“捎带”查多条,从而减少 SQL 次数。
🧩 什么是 Hibernate 的 Batch Fetching?
当你懒加载关联对象时(如 @ManyToOne、@OneToMany 等),Hibernate 默认是一条记录触发一次查询。
Batch Fetching 让它一次性多加载几个,减少 SQL 次数。
比如你加载了 10 个 User,每个 User 懒加载 Department。
默认是触发 10 次查询。
但设置了 batch size 为 5 后,它会每 5 个批量加载,只用 2 次查询。
🛠 怎么启用?
1. 在配置文件中开启:
在 application.properties 或 application.yml 里加上:
spring.jpa.properties.hibernate.default_batch_fetch_size=16
或者在 XML 配置、persistence.xml 中配置:
<property name="hibernate.default_batch_fetch_size" value="16"/>
也可以通过代码配置:
props.put("hibernate.default_batch_fetch_size", "16");
2. 支持的关联类型?
关联类型 |
是否支持 batch fetching |
---|---|
@ManyToOne |
✅ 支持 |
@OneToOne |
✅ 支持 |
@OneToMany |
⚠️ 有条件支持(最好配合 @BatchSize) |
@ManyToMany |
⚠️ 视情况而定 |
3. 还可以用 @BatchSize 精细控制
@Entity
public class User {
@ManyToOne(fetch = FetchType.LAZY)
@BatchSize(size = 20) // 只对这个字段启用 batch fetching
private Department department;
}
🚫 不是主动查询的 size
你说得对,“我自己设置查询 size”那是你主动用 limit 或分页查多少条。而 batch fetching 是在懒加载的时候,Hibernate 自动帮你优化,不需要你改业务逻辑。
✅ 示例总结
没配置时:
select * from user;
select * from department where id = 1;
select * from department where id = 2;
...
配置了 batch size = 5 后:
select * from user;
select * from department where id in (1,2,3,4,5);
select * from department where id in (6,7,8,9,10);
SQL 次数减少,性能提升。