1. 迫切左外链接
- 在关系型数据库之中,数据表和数据表之间是可以存在关系的,因此不但可以查询数据表内的数据还可以通过数据表和数据表之间的关系来查询关联数据表中的数据.
- 例如:一个Employee表描述一个雇员的信息,其中有一个"id"字段描述雇员的编号,还有一个Department表描述一个部门的信息.每个雇员属于一个部门.
- 那么每一个雇员中包含一个"did"字段该于部门表中的部门id字段是有关联的.所以就可以通过部门表中的来查询雇员表中的信息.
- 这就需要使用到外链接的方式.
- LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
- list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化, 存放所有关联的 Employee 的实体对象.
- 查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
- 具体使用
@Test
public void tsetLeftJOINFetch(){
String hql = "FROM Department d LEFT JOIN FETCH d.emps";
Query query = this.session.createQuery(hql);
List<Department> list = query.list();
System.out.println(list.size());
}
- 得到的结果
- 现在的Department表中只有10个部门,而却查出了100条数据,这是因为有些雇员所属的部门是相同的,所以会出现重复的数据,如果要消除这些数据最好的办法就是使用"DISTINCT"关键字消除重复的数据
- 修改hql语句消除重复数据
@Test
public void tsetLeftJOINFetch(){
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps";
Query query = this.session.createQuery(hql);
List<Department> list = query.list();
System.out.println(list.size());
}
- 还有一种消除重复数据的方式将Query的list()方法返回的结果集合,使用HashSet类进行包装之后消除重复数据.
@Test
public void tsetLeftJOINFetch(){
String hql = "FROM Department d LEFT JOIN FETCH d.emps";
Query query = this.session.createQuery(hql);
List<Department> list = new ArrayList<Department>(new LinkedHashSet<Department>( query.list()));
System.out.println(list.size());
}
- 在使用迫切左外链接的时候,每一个Department的实例化对象中的"emps"集合都已经实例化完成了.
@Test
public void tsetLeftJOINFetch(){
FETCH d.emps";
String hql = "FROM Department d LEFT JOIN FETCH d.emps";
Query query = this.session.createQuery(hql);
List<Department> list = new ArrayList<Department>(new LinkedHashSet<Department>( query.list()));
System.out.println(list.size());
for (Department d : list){
System.out.println("部门名称:"+d.getName()+" 雇员人数: "+d.getEmps().size());
}
}
2. 左外链接
- LEFT JOIN 关键字表示左外连接查询.
- list() 方法返回的集合中存放的是对象数组类型
- 根据配置文件来决定 Employee 集合的检索策略.
- 如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT 关键字
- 实际应用
@Test
public void testLeftJoin(){
String hql = "FROM Department d LEFT JOIN d.emps";
Query query = this.session.createQuery(hql);
List list = query.list();
System.out.println(list);
}
-
得到的结果
-
迫切做外链接和左链接最大的区别就在于:
- 迫切左外链接返回的结果是一个实例化好的持续化类对象(Department)
- 而左外链接返回的结果是一个对象数组,对象数组操作起来比较繁琐,因此使用迫切左外链接更为合适.
-
如果希望左外链接返回的集合中是一个Department实例化对象,可以在hql语句中使用"SELECT"语句完成
@Test
public void testLeftJoin(){
// String hql = "FROM Department d LEFT JOIN d.emps";
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
Query query = this.session.createQuery(hql);
List list = query.list();
System.out.println(list);
}
3. 迫切内链接
- INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
- list() 方法返回的集合中存放 Department 对象的引用, 每个 Department 对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
- 具体使用
@Test
public void tsetInnerJoinFetch(){
String hql = "SELECT DISTINCT d FROM Department d INNER JOIN FETCH d.emps";
Query query = this.session.createQuery(hql);
List<Department> list = query.list();
System.out.println(list);
}
4. 内连接
- INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
- list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型
- 如果希望 list() 方法的返回的集合仅包含 Department 对象, 可以在 HQL 查询语句中使用 SELECT 关键字
@Test
public void tsetInnerJoin(){
String hql = "FROM Department d INNER JOIN d.emps";
Query query = this.session.createQuery(hql);
List list = query.list();
System.out.println(list);
}
- 内连接返回默认也是对象数组
- 如果希望返回的是实例化的持久化对象,也可以通过"SELECT"关键字完成
String hql = "SELECT DISTINCT d FROM Department d INNER JOIN d.emps";
关联级别运行时的检索策略
- 如果在 HQL 中没有显式指定检索策略, 将使用映射文件配置的检索策略.
- HQL 会忽略映射文件中设置的迫切左外连接检索策略, 如果希望 HQL 采用迫切左外连接策略, 就必须在 HQL 查询语句中显式的指定它
- 若在 HQL 代码中显式指定了检索策略, 就会覆盖映射文件中配置的检索策略