迫切左外连接:
LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化, 存放所有关联的 Employee 的实体对象.
查询结果中可能会包含重复元素, 可以通过一个 HashSet 或 DISTINCT 关键字 来过滤重复元素
@Test
public void testGedefffde(){
String hqlString=" FROM Grade g LEFT JOIN FETCH g.students ";
Query query=session.createQuery(hqlString);
//这是第二种,去重方法
List<Grade> list = query.list();
list=new ArrayList<>(new LinkedHashSet(list));
for(Grade grade: list)
System.out.println(grade.getName()+"--"+grade.getGradeId()+"--"+grade.getStudents().size());
}
注意:from 的表名是和cfg.xml对应,不是和数据库的对应。其余也是同样道理。
左外连接:
LEFT JOIN 关键字表示左外连接查询.
list() 方法返回的集合中存放的是对象数组类型
根据配置文件来决定 Employee 集合的检索策略.
如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT DISTINCT关键字,SELECT导致返回对象的引用,DISTINCT去重
@Test
public void testGedefswffde(){
//因为加上了select diatinct 关键字,返回对象
String hqlString="select distinct g FROM Grade g LEFT JOIN g.students ";
Query query=session.createQuery(hqlString);
List<Grade> list = query.list();
for(Grade object:list){
System.out.println(object.getName()+"---"+object.getStudents());
}
}
区别
- 两个查询方式所发送的sql语句是相同的,如下所示。
- 迫切连接的 fetch 关键字是告诉hibernate框架,将student的引用也直接初始化。
- 而且,迫切连接返回的是一个对象。但普通左外连接,就只是一个数组,需要加上select distinct 关键字后才能打包成对象。
- 普通左外连接没有初始化student,只有使用的时候才会真正初始化
select
distinct grade0_.GRADE_ID as GRADE_ID1_1_,
grade0_.NAME as NAME2_1_,
grade0_.PERSON_SUM as PERSON_S3_1_
from
hibernate.GRADE grade0_
left outer join
hibernate.STUDENT students1_
on grade0_.GRADE_ID=students1_.GRADE
迫切内连接
INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
list() 方法返回的集合中存放 Department 对象的引用, 每个 Department 对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
内连接:
INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型
如果希望 list() 方法的返回的集合仅包含 Department 对象, 可以在 HQL 查询语句中使用 SELECT DISTINCT关键字,SELECT导致返回对象的引用,DISTINCT去重
关联级别运行时的检索策略
如果在 HQL 中没有显式指定检索策略, 将使用映射文件配置的检索策略.
HQL 会忽略映射文件中设置的迫切左外连接检索策略, 如果希望 HQL 采用迫切左外连接策略, 就必须在 HQL 查询语句中显式的指定它
若在 HQL 代码中显式指定了检索策略, 就会覆盖映射文件中配置的检索策略