寻找可信和/或官方来源的答案。
JBoss ORM文档怎么样?
https://docs.jboss.org/hibernate/orm/current/userguide/html_single/chapters/fetching/Fetching.html
有一些定义数据获取的范围:
静态
在映射中静态定义获取策略。在没有动态定义策略的情况下,使用静态定义的获取策略。
SELECT
执行单独的SQL查询来加载数据。这可以是EAGER(第二个查询立即发出)或LAZY(第二个查询延迟到需要数据时再发出)。这通常被称为N+1策略。
JOIN
本质上是EAGER样式的获取。通过使用SQL外连接来获取要获取的数据。
BATCH
执行单独的SQL查询来加载一些相关数据项,使用批处理大小作为SQL WHERE子句的IN限制的一部分。同样,这可以是EAGER(第二个查询立即发出)或LAZY(第二个查询延迟到需要数据时再发出)。
SUBSELECT
执行单独的SQL查询来基于用于加载所有者的SQL限制加载关联数据。同样,这可以是EAGER(第二个查询立即发出)或LAZY(第二个查询延迟到需要数据时再发出)。
动态
动态定义实际上是针对用例的。有多种方式定义动态获取:
在映射中定义获取配置文件,但可以在会话中启用/禁用。
HQL/JPQL和Hibernate和JPA标准查询都有指定特定查询的获取能力。
实体图形从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<>()
现在,我们将获取所有符合给定过滤条件的Department实体,然后浏览它们的员工集合。Hibernate将通过生成单个SQL语句来初始化先前获取的所有Department实体的所有员工集合来避免N+1查询问题。而不是使用所有实体标识符,Hibernate只需重新运行先前获取Department实体的查询。示例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%'
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%'
)