从可靠和/或官方来源寻找答案。
JBoss ORM 文档怎么样?
https://docs.jboss.org/hibernate/orm/current/userguide/html_single/chapters/fetching/Fetching.html
定义抓取的范围有很多:
static
抓取策略的静态定义是在
映射。静态定义的获取策略用于
没有任何动态定义的策略
SELECT 执行单独的 SQL 选择以加载数据。这个可以
要么是 EAGER(立即发出第二个选择)要么是 LAZY(
第二次选择被延迟,直到需要数据)。这是
通常称为 N+1 的策略。
JOIN 本质上是一种 EAGER 的获取方式。要获取的数据是
通过使用 SQL 外连接获得。
BATCH 执行单独的 SQL 选择以加载许多相关数据
项目使用 IN 限制作为 SQL WHERE 子句的一部分,基于
批量大小。同样,这可以是 EAGER(第二个选择是
立即发出)或 LAZY(第二次选择延迟到
需要数据)。
SUBSELECT 执行单独的 SQL 选择以加载基于关联的数据
关于用于加载所有者的 SQL 限制。同样,这可以
是 EAGER(立即发出第二个选择)或 LAZY(第二个
select 会延迟到需要数据为止)。
动态(有时称为运行时)
动态定义确实以用例为中心。有多种定义动态的方法
获取:
获取配置文件在映射中定义,但可以在
会话。
HQL/JPQL 和 Hibernate 和 JPA Criteria 查询都有能力
指定获取,特定于所述查询。
实体图 从 Hibernate 4.2 (JPA 2.1) 开始,这也是一个
选项。
为了证明上面的答案,这里有一个例子:
FetchMode.SUBSELECT 为了演示 FetchMode.SUBSELECT 的工作原理,我们
将修改 FetchMode.SELECT 映射示例以使用
FetchMode.SUBSELECT:
示例 17. FetchMode.SUBSELECT 映射示例:
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
@Fetch(FetchMode.SUBSELECT)
private List<Employee> employees = new ArrayList<>();
现在,我们将获取与给定匹配的所有部门实体
过滤条件,然后浏览他们的员工集合。
Hibernate 将通过生成单个查询来避免 N+1 查询问题
初始化所有员工集合的 SQL 语句
之前获取的部门实体。而不是使用
传递所有实体标识符,Hibernate 只是重新运行前一个
获取部门实体的查询。
示例 18. FetchMode.SUBSELECT 映射示例:
List<Department> departments = entityManager.createQuery(
"select d " +
"from Department d " +
"where d.name like :token", Department.class)
.setParameter( "token", "Department%" )
.getResultList();
log.infof( "Fetched %d Departments", departments.size());
for (Department department : departments ) {
assertEquals(3, department.getEmployees().size());
}
-- 获取 2 个部门
SELECT
d.id as id1_0_
FROM
Department d
where
d.name like 'Department%'
-- Fetched 2 Departments
SELECT
e.department_id as departme3_1_1_,
e.id as id1_1_1_,
e.id as id1_1_0_,
e.department_id as departme3_1_0_,
e.username as username2_1_0_
FROM
Employee e
WHERE
e.department_id in (
SELECT
fetchmodes0_.id
FROM
Department fetchmodes0_
WHERE
d.name like 'Department%'
)