Hibernate(十四):HQL查询(三)
背景
基于上两章节《Hibernate(十二):HQL查询(一)》、《Hibernate(十三):HQL查询(二)》,已经学习了一部分关于HQL的用法:
- HQL带参数查询
- HQL Order By排序查询
- HQL 设置实体参数查询
- HQL分页查询
- HQL命名语句查询
- HQL投影查询
- HQL报表查询
本章节将会学习:HQL(迫切)左外连接、HQL(迫切)内连接、总结关联级别运行时的检索策略。
HQL(迫切)左外连接
迫切左外连接
1)LEFT JOIN FETCH 关键字表示迫切左外连接检索策略
2)list()方法返回的集合中存放实体对象的引用,每个Department对象关联的Employee结合都被初始化,存放所有关联的Employee的实体对象
3)查询结果中可能会被包含重复的元素,可以通过HashSet来过滤重复元素,也可以在hql语句中使用distinct.
测试代码:
@Test
public void testLeftJoinFetch() {
String hql = "FROM Department d LEFT JOIN FETCH d.employees";
List<Department> departs = session.createQuery(hql).list(); System.out.println("直接左外连接查询结果集合个数:" + departs.size());
Department depart = departs.get(0);
System.out.println("直接左外连接查询结果集的第一个元素Department Name:" + depart.getName() + ",该department的Employees个数:" + depart.getEmployees().size()); departs = new ArrayList<>(new LinkedHashSet<>(departs));
System.out.println("使用LinkedHashSet排除重复项后集合个数:" + departs.size()); hql = "Select Distinct d FROM Department d LEFT JOIN FETCH d.employees";
List<Department> departs2 = session.createQuery(hql).list();
System.out.println("使用Distinct排除重复项后集合个数:" + departs2.size());
for(Department department : departs2){
System.out.println("使用Distinct排除重复项后元素Department Name:" + department.getName() + ",该department的Employees个数:" + department.getEmployees().size());
}
}
执行sql及结果:
Hibernate:
select
department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_0__,
employees1_.ID as ID1_1_0__
from
DX_DEPARTMENT department0_
left outer join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
直接左外连接查询结果集合个数:80
直接左外连接查询结果集的第一个元素Department Name:开发部门,该department的Employees个数:16
使用LinkedHashSet排除重复项后集合个数:5
Hibernate:
select
distinct department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_0__,
employees1_.ID as ID1_1_0__
from
DX_DEPARTMENT department0_
left outer join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
使用Distinct排除重复项后集合个数:5
使用Distinct排除重复项后元素Department Name:开发部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:测试部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:业务部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:财务部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:行政部门,该department的Employees个数:16
左外连接
1)LEFT JOIN 关键字表示左外连接查询
2)list()方法返回的集合中存放的是数组类型
3)根据配置文件来决定Employee集合的策略(以下测试代码,前提是employee.hbm.xml中没有配置join='fetch'策略)
4)如果希望list()方法返回的集合中仅包含Department对象,可以在HQL查询语句中使用SELECT关键字。
测试代码:
@Test
public void testLeftJoin() {
String hql = "FROM Department d LEFT JOIN d.employees";
List<Department> departs = session.createQuery(hql).list(); System.out.println("直接左外连接查询结果集合个数:" + departs.size());
// 将会抛出异常:
//Department depart = departs.get(0);
//System.out.println("直接左外连接查询结果集的第一个元素Department Name:" + depart.getName() + ",该department的Employees个数:" + depart.getEmployees().size()); // 排重无效
departs = new ArrayList<>(new LinkedHashSet<>(departs));
System.out.println("使用LinkedHashSet排除重复项后集合个数:" + departs.size()); hql = "Select Distinct d FROM Department d LEFT JOIN d.employees";
List<Department> departs2 = session.createQuery(hql).list();
System.out.println("使用Distinct排除重复项后集合个数:" + departs2.size());
for(Department department : departs2){
System.out.println("使用Distinct排除重复项后元素Department Name:" + department.getName() + ",该department的Employees个数:" + department.getEmployees().size());
}
}
执行sql及结果
Hibernate:
select
department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_DEPARTMENT department0_
left outer join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
直接左外连接查询结果集合个数:80
使用LinkedHashSet排除重复项后集合个数:80
Hibernate:
select
distinct department0_.ID as ID1_0_,
department0_.NAME as NAME2_0_
from
DX_DEPARTMENT department0_
left outer join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
使用Distinct排除重复项后集合个数:5
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:开发部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:测试部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:业务部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:财务部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:行政部门,该department的Employees个数:16
HQL(迫切)内连接
迫切内连接
1)INNER JOIN FETCH关键字表示迫切内连接,也可以省略INNER关键字
2)list()方法返回的集合中存放Department对象的引用,每个Department对象的Employee集合都被初始化,存放所有关联的Employee对象。
测试函数:
@Test
public void testInnerJoinFetch() {
// // 先执行追加employee一条记录。
// Employee employee = new Employee("name", 10000, "email@test.com");
// session.save(employee);
// Department department = new Department("党政部门");
// session.save(department); String hql = "FROM Department d INNER JOIN FETCH d.employees";
List<Department> departs = session.createQuery(hql).list(); System.out.println("直接左外连接查询结果集合个数:" + departs.size());
Department depart = departs.get(0);
System.out.println("直接左外连接查询结果集的第一个元素Department Name:" + depart.getName() + ",该department的Employees个数:" + depart.getEmployees().size()); departs = new ArrayList<>(new LinkedHashSet<>(departs));
System.out.println("使用LinkedHashSet排除重复项后集合个数:" + departs.size()); hql = "Select Distinct d FROM Department d INNER JOIN FETCH d.employees";
List<Department> departs2 = session.createQuery(hql).list();
System.out.println("使用Distinct排除重复项后集合个数:" + departs2.size());
for (Department department : departs2) {
System.out.println("使用Distinct排除重复项后元素Department Name:" + department.getName() + ",该department的Employees个数:" + department.getEmployees().size());
}
}
执行sql及结果:
Hibernate:
select
department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_0__,
employees1_.ID as ID1_1_0__
from
DX_DEPARTMENT department0_
inner join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
直接左外连接查询结果集合个数:80
直接左外连接查询结果集的第一个元素Department Name:开发部门,该department的Employees个数:16
使用LinkedHashSet排除重复项后集合个数:5
Hibernate:
select
distinct department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_0__,
employees1_.ID as ID1_1_0__
from
DX_DEPARTMENT department0_
inner join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
使用Distinct排除重复项后集合个数:5
使用Distinct排除重复项后元素Department Name:开发部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:测试部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:业务部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:财务部门,该department的Employees个数:16
使用Distinct排除重复项后元素Department Name:行政部门,该department的Employees个数:16
内连接
1)INNER JOIN 关键字表示内连接,也可以省略INNER 关键字
2)list()方法的集合中存放的每个元素对应查询结果的一条记录,每个元素都是对象数组
3)如果希望list()方法的返回集合仅包含Department对象,可以在HQL查询语句中使用SELECT关键字。
测试函数:
@Test
public void testInnerJoin() {
String hql = "FROM Department d INNER JOIN d.employees";
List<Department> departs = session.createQuery(hql).list(); System.out.println("直接左外连接查询结果集合个数:" + departs.size());
// 将会抛出异常:
// Department depart = departs.get(0);
// System.out.println("直接左外连接查询结果集的第一个元素Department Name:"
// +depart.getName() + ",该department的Employees个数:" +
// depart.getEmployees().size()); // 排重无效
departs = new ArrayList<>(new LinkedHashSet<>(departs));
System.out.println("使用LinkedHashSet排除重复项后集合个数:" + departs.size()); hql = "Select Distinct d FROM Department d INNER JOIN d.employees";
List<Department> departs2 = session.createQuery(hql).list();
System.out.println("使用Distinct排除重复项后集合个数:" + departs2.size());
for (Department department : departs2) {
System.out.println("使用Distinct排除重复项后元素Department Name:" + department.getName() + ",该department的Employees个数:" + department.getEmployees().size());
}
}
执行sql及结果:
Hibernate:
select
department0_.ID as ID1_0_0_,
employees1_.ID as ID1_1_1_,
department0_.NAME as NAME2_0_0_,
employees1_.NAME as NAME2_1_1_,
employees1_.SALARY as SALARY3_1_1_,
employees1_.EMAIL as EMAIL4_1_1_,
employees1_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_DEPARTMENT department0_
inner join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
直接左外连接查询结果集合个数:80
使用LinkedHashSet排除重复项后集合个数:80
Hibernate:
select
distinct department0_.ID as ID1_0_,
department0_.NAME as NAME2_0_
from
DX_DEPARTMENT department0_
inner join
DX_EMPLOYEE employees1_
on department0_.ID=employees1_.DEPARTMENT_ID
使用Distinct排除重复项后集合个数:5
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:开发部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:测试部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:业务部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:财务部门,该department的Employees个数:16
Hibernate:
select
employees0_.DEPARTMENT_ID as DEPARTME5_1_0_,
employees0_.ID as ID1_1_0_,
employees0_.ID as ID1_1_1_,
employees0_.NAME as NAME2_1_1_,
employees0_.SALARY as SALARY3_1_1_,
employees0_.EMAIL as EMAIL4_1_1_,
employees0_.DEPARTMENT_ID as DEPARTME5_1_1_
from
DX_EMPLOYEE employees0_
where
employees0_.DEPARTMENT_ID=?
使用Distinct排除重复项后元素Department Name:行政部门,该department的Employees个数:16
总结关联级别运行时的检索策略
1)如果在HQL中没有显式指定检索策略,将使用映射文件配置的检索策略
2)HQL会忽略映射文件中设置的迫切左外连接检索策略,如果HQL采用迫切左外连接策略,就必须在HQL查询语句中显式的指定它
3)若在HQL代码中显式指定了检索策略,就会覆盖映射文件中配置的检索策略。
Hibernate(十四):HQL查询(三)的更多相关文章
- Hibernate中关于HQL查询返回List<Object>数据的结果集问题
---恢复内容开始--- 开发中遇到的一个小问题,使用Hibernate中的HQL查询时,使用query.list()查询出来的是一个List<Object>结果集 原来代码: publi ...
- Hibernate的四种查询方式(主键查询,HQL查询,Criteria查询,本地sql查询)和修改和添加
Hibernate的添加,修改,查询(三种查询方式)的方法: 案例演示: 1:第一步,导包,老生常谈了都是,省略: 2:第二步,创建数据库和数据表,表结构如下所示: 3:第三步创建实体类User.ja ...
- Hibernate第四天——查询方式
Hibernate入门最后一天第四天,我们进行查询方式的更进一步的细化: 先看一下大致的Hibernate的提供的查询的方式: 1.对象导航查询 2.OID查询 3.HQL查询 4.QBC查询 5.本 ...
- 【Hibernate步步为营】--hql查询小介
HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...
- hibernate学习(7)——HQL查询
1.HQL查询定义 Hibernate查询分类: 1. get/load 根据OID检索 2. 对象视图检索 c.getOrders 3. Sql语句 createSqlQuery 4. Hql语句 ...
- Hibernate框架之HQL查询与Criteria 查询的区别
Hibernate框架提供了HQL查询和Criteria 查询.下面对这两种查询分别做个例子.也好对这两种查询方法有个大概的了解.就用房屋信息表做例子,查询所有房屋信息. HQL语句查询所有房屋信息: ...
- Hibernate用到HQL查询时的错误
Exception in thread "main" org.hibernate.hql.internal.ast.QuerySyntaxException: student is ...
- Hibernate(十二)Criteria查询
一.简述 Criteria是一种比hql更面向对象的查询方式.Criteria 可使用 Criterion 和 Projection 设置查询条件.可以设置 FetchMode(联合查询抓取的模式 ) ...
- Java_Web三大框架之Hibernate+jsp+selvect+HQL查询数据
俗话说:"好记性不如烂笔头".本人学习Hibernate也有一个星期了,对Hibernate也有一个初步的了解.下面对Hibernate显示数据做个笔记,使用租房系统的Hibern ...
- Hibernate学习之hql查询语句
* 页面上数据的字段和数据库中字段差不多,这个时候,采用迫切连接 结构比较好,如果页面上的字段很少,要按照需求加载数据,采用带构造函数的select查询 实例讲解:转自:http://www.cn ...
随机推荐
- 微软Skype Linux客户端全新发布
前两天,微软说要给“Linux 用户带来一个令人兴奋的新闻”,今天,这个新闻来了.它刚刚为 Linux 发布了一个新的 Skype 客户端. 此次发布,微软为 Linux 带来的 Skype 客户端与 ...
- python函数式编程之生成器
在前面的学习过程中,我们知道,迭代器有两个好处: 一是不依赖索引的统一的迭代方法 二是惰性计算,节省内存 但是迭代器也有自己的显著的缺点,那就是 不如按照索引取值方便 一次性,只能向后取值,不能向前取 ...
- 二分partition算法应用
一个二分partition算法,将整个数组分解为小于某个数和大于某个数的两个部分,然后递归进行排序算法. 法一: int partition(vector<int>&arr, in ...
- rocketMq概念介绍
rocketMq官网 http://rocketmq.apache.org/ rocketMq逻辑概念介绍 rocketMq逻辑图 备注: 改图片分享自李占卫的网上家园 说明: 在rocketM ...
- window7 安装sass和compass
官网有详细的介绍,但是安装时候还是出现了一些小问题. 首先下载Rudy,然后根据提示勾选加入环境变量,由于第一次使用,我就选择了" msys2 base installlation" ...
- 使用pm2躺着实现负载均衡
事实上,pm2 是一个带有负载均衡功能的Node应用的进程管理器,Node实现进程管理的库有很多,forever也是其中一个很强大但是也相对较老的进程管理器. 为什么要使用pm2 对于这个问题,先说说 ...
- 2018最新版本Sublime Text3注册码(仅供测试交流使用)
-– BEGIN LICENSE -– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA ...
- MySQL数据库操作类(PHP实现,支持连贯操作)
<?php /** * Author: suvan * CreateTime: 2018/2/27 * description: 数据库操作类(仅对接MySQL数据库,主要利用MySQLi函数) ...
- Beta 第二天
今天遇到的困难: 组员对github极度的不适应 Android Studio版本不一致项目难以打开运行 移植云端的时候,愚蠢的把所有项目开发环境全部搬上去.本身云的内存小,性能差,我们花费了太多时间 ...
- 团队项目7——团队冲刺(beta版本)
beta版本冲刺计划安排:http://www.cnblogs.com/ricardoCYF/p/8018413.html 12.06:http://www.cnblogs.com/ricardoCY ...