HQL的检索方式
HQL是面向持久化类的,所以需要查询表的字段都要用持久化类指定
例如
String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept";
Query query = session.createQuery(hql);
我们要查询表Employees的Email字段,但是我们不能直接select Email from empolyees,而是要通过持久化类来指定
SELECT e.email FROM Employee e
这也是HQL好处之一,面向持久化类,不面向数据裤,进而无论你换了其它什么数据库,语句还是可以正常运行
这一点要谨记
1分页查询:
setFirstResult(int firstResult): 设定从哪一个对象开始检索, 参数 firstResult 表示这个对象在查询结果中的索引位置, 索引位置的起始值为 0. 默认情况下, Query 从查询结果中的第一个对象开始检索 (setFirstResult=BeginData,,就是从第几条记录开始查询)
setMaxResults(int maxResults): 设定一次最多检索出的对象的数目. 在默认情况下, Query 和 Criteria 接口检索出查询结果中所有的对象 有了这两个,不用管底层数据库是怎样实现的 setMaxResults=pageSize(设定了每页显示的记录数)
example:
@Test
public void testPageQuery(){
String hql = "FROM Employee";
Query query = session.createQuery(hql); int pageNo = 22;
int pageSize = 5;
//显示第21页的记录,当setMaxResults设置值后,也就规定了数据表的记录分为多少页了
List<Employee> emps =query.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
System.out.println(emps);
}
2在映射文件中定义命名查询语句
Hibernate 允许在映射文件中定义字符串形式的查询语句.
<query> 元素用于定义一个 HQL 查询语句, 它和 <class> 元素并列. 因为了是在xml文件中定义,为了尽量不引起歧义,所以HQL语句尽量保存在<![cdata[这里]]>这一点需要特别的注意 示例:
<query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
在程序中通过 Session 的 getNamedQuery() 方法获取查询语句对应的 Query 对象.
@Test
public void testNamedQuery(){
Query query = session.getNamedQuery("salaryEmps");//取得在.hbm.xml文件定义的HQL语句 List<Employee> emps = query.setFloat("minSal", 5000)
.setFloat("maxSal", 10000)
.list(); System.out.println(emps.size());
}
3投影查询
投影查询: 查询结果仅包含实体的部分属性. 通过 SELECT 关键字实现.,就是查询部分属性(select那里声明,与SQL一样)
1做法一:Query 的 list() 方法返回的是集合数组类型的元素(就是list方法返回了一个list对象), 每个对象数组代表查询结果的一条记录(所以必须用list<Objec[]>来存储)
example:
@Test
public void testFieldQuery(){
String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept";
Query query = session.createQuery(hql); Department dept = new Department();
dept.setId(80);
//返回的是list对象,所以要用list<object []>数组存储起来
List<Object[]> result = query.setEntity("dept", dept)
.list(); for(Object [] objs: result){
System.out.println(Arrays.asList(objs));
}
}
2做法二:可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,也就是说咋们返回多少个参数,就定义一个该对象对应的参数构造器,把返回的数据封装到一个对象里,这样更加容易遍历 使程序代码能完全运用面向对象的语义来访问查询结果集.
example:
@Test
public void testFieldQuery2(){
//把返回的参数都封装给一个employee对象,但是前提必须要有对应的构造器
String hql = "SELECT new Employee(e.email, e.salary, e.dept) "
+ "FROM Employee e "
+ "WHERE e.dept = :dept";
Query query = session.createQuery(hql); Department dept = new Department();
dept.setId(80);
List<Employee> result = query.setEntity("dept", dept)
.list(); for(Employee emp: result){
System.out.println(emp.getId() + ", " + emp.getEmail()
+ ", " + emp.getSalary() + ", " + emp.getDept());
}
}
可以通过 DISTINCT 关键字来保证查询结果不会返回重复元素
4报表查询
报表查询(就是对数据排序,分组,进行一定的筛选)
报表查询用于对数据分组和统计, 与 SQL 一样, HQL 利用 GROUP BY 关键字对数据分组, 用 HAVING 关键字对分组数据设定约束条件.(这些关键字的用法和SQL一样所以没啥好说的)
在 HQL 查询语句中可以调用以下聚集函数 count() min() max() sum() avg()
example:
@Test
public void testGroupBy(){
//用"+"号连接HQL语句时记得要用双引号(""),
String hql = "SELECT min(e.salary), max(e.salary) "
+ "FROM Employee e "
+ "GROUP BY e.dept "
+ "HAVING min(salary) > :minSal"; Query query = session.createQuery(hql)
.setFloat("minSal", 8000); List<Object []> result = query.list();
for(Object [] objs: result){
System.out.println(Arrays.asList(objs));
}
}
5(迫切)左外连接
左外连接:显示join左边表的所有数据,也就是from 那个表,比如 from student left join teacher on s_id=t_id显示student的所有数据,teacher中不符合条件的数据将被显示为null
迫切左外连接: (推荐在多对一和一对一查询数据时使用这个)
1)LEFT JOIN FETCH 关键字表示迫切左外连接检索策略. (就是fetch取值为join)
2)list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化, 存放所有关联的Employee 的实体对象.
3)查询结果中可能会包含重复元素, 可以通过一个 HashSet或者 DISTINCT 来过滤重复元素
左外连接:
1)LEFT JOIN 关键字表示左外连接查询.
2)list() 方法返回的集合中存放的是对象数组类型
(集合对象是被初始化了,但是集合对象的对象没有被初始化,)
例如list<department>,而department中又有一个employee对象,此时department对象已经被初始化了,而employee对象并没有被初始化
也可以这样理解连接的右表对象并没有被初始化,例如:
from department left join employee on d_id=e_id
也就说此时department对象被初始化了,employee对象没有被初始化,
3)根据配置文件来决定 Employee 集合的检索策略.(fetch的取值)
4)如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT 关键字
6(迫切)内连接
内连接:两个表的记录同时符合连接条件才会被显示
例如:from student left join teacher on s_id=t_id
student和teacher的记录同时符合条件才会被显示
迫切内连接:
INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
list() 方法返回的集合中存放 Department 对象的引用, 每个 Department 对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象
内连接:
INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型 如果希望 list() 方法的返回的集合仅包含 Department 对象, 可以在 HQL 查询语句中使用 SELECT 关键字
关联级别策略
如果在 HQL 中没有显式指定检索策略, 将使用映射文件配置的检索策略. HQL 会忽略映射文件中设置的迫切左外连接检索策略, 如果希望 HQL 采用迫切左外连接策略, 就必须在 HQL 查询语句中显式的指定它 若在 HQL 代码中显式指定了检索策略, 就会覆盖映射文件中配置的检索策略
HQL的检索方式的更多相关文章
- 【Hibernate】检索方式
一.概述 二.HQL 2.1 简介 2.2 查询所有记录 2.3 查询使用别名 2.4 排序 2.5 分页查询 2.6 单个对象查询 2.7 参数绑定 2.8 投影操作 2.9 模糊查询 2.10 S ...
- Hibernate之检索方式
时间:2017-1-22 16:09 --检索方式Hibernate中提供了以下几种检索对象的方式: * 导航对象图检索方式 根据已经加载额对象导航到其他对象. ...
- Hibernate —— HQL、QBC检索方式
一.HQL 检索方式 以双向的一对多来测试 HQL 检索方式.以 Department 和 Employee 为例. 建表语句: CREATE TABLE department ( dept_id ) ...
- hibernate检索方式(HQL 检索方式,QBC 检索方式,本地 SQL 检索方式)
hibernate有五种检索方式,这儿用 单向的一对多的映射关系 例子,这儿有后三种的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 OID 检索方式: 按照对象的 OID 来检索对象 ...
- [原创]java WEB学习笔记89:Hibernate学习之路-- -Hibernate检索方式(5种),HQL介绍,实现功能,实现步骤,
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate 检索方式之 HQL 检索方式
HQL(Hibernate Query Language) 是面向对象的查询语言,它和 SQL 查询语言有些相似.在 Hibernate 提供的各种检索方式中,HQL 是使用最广的一种检索方式,它有如 ...
- Hibernate -- 检索方式 HQL
Hibernate 提供了以下几种检索对象的方式 导航对象图检索方式: 根据已经加载的对象导航到其他对象 OID 检索方式: 按照对象的OID 来检索对象 HQL 检索方式:使用面向对象的HQL查询 ...
- Hibernate的检索方式
Hibernate的检索方式 检索方式(查询的方式) 导航对象图检索方式: 根据已经加载的对象导航到其他对象 Customer customer = (Customer)session.get(Cus ...
- 攻城狮在路上(壹) Hibernate(十四)--- Hibernate的检索方式(下)
本节介绍HQL和QBC的高级用法:各种连接查询.投影查询.报表查询.动态查询.集合过滤和子查询等.另外将归纳优化查询程序代码,从而提高查询性能的各种技巧.一.连接查询: HQL与QBC支持的各种连接类 ...
随机推荐
- [Jobdu] 题目1139:最大子矩阵
题目描述: 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵.比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 ...
- 【Android】13.0 第13章 创建和访问SQLite数据库—本章示例主界面
分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 Android 内置了三种数据存取方式:SQLite数据库.文件.SharedPreferences. 这一章我们 ...
- CSS3 图片旋转
.nav_all { position:relative; z-index:; width:172px; display:inline; ; } .nav_all b { display:block; ...
- redis使用场景介绍
一:缓存——热数据 热点数据(经常会被查询,但是不经常被修改或者删除的数据),首选是使用redis缓存,毕竟强大到冒泡的QPS和极强的稳定性不是所有类似工具都有的,而且相比于memcached还提供了 ...
- github上搭建网站前台页面
其实就是把html页面提交到github,为了能在线演示: 1. 首先在github网站找到你的项目 2. 点击设置 3. 找到这几个选项,选择master branch打钩,然后保存 4. 然后就会 ...
- Linux下清空缓冲区的方法
Linux下清空缓冲区的方法 C标准规定fflush()函数是用来刷新输出(stdout)缓存的.对于输入(stdin),它是没有定义的.但是有些编译器也定义了fflush( stdin )的实现,比 ...
- springboot集成jdbcTemplate
这里使用springboot自带的jdbcTemplate连接mysql数据库 1. 添加依赖包 <!-- jdbc --> <dependency> <groupId& ...
- oozie调度hive脚本demo
1. 环境配置 2. 脚本配置 3. 执行job 4. 查看结果 待发布 ..
- mvc 返回list数据 页面 mode
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<实体命名空间& ...
- MySQL 5.6的72个新特性(译)
一,安全提高 1.提供保存加密认证信息的方法,使用.mylogin.cnf文件.使用 mysql_config_editor可以创建此文件.这个文件可以进行连接数据库的访问授权. mysql_conf ...