背景

基于上一章节《Hibernate(十二):HQL查询(一)》,已经学习了一部分关于HQL的用法:

  1. HQL带参数查询
  2. HQL Order By排序查询
  3. HQL 设置实体参数查询

本章节将会学习:HQL分页查询、HQL命名语句查询、HQL投影查询、HQL报表查询。

HQL分页查询

1)setFirstResult(int firstResult):设定从哪一个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0。默认情况下,Query从查询结果中的第一个对象开始检索。

2)setMaxResults(int maxResults):设定一次最多检索出的对象的数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。

     @Test
public void testHQLPageQuery() {
String hql = "From Employee"; int pageNum = 1;
int pageSize = 10;
Query query = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}

执行sql及结果:

 Hibernate:
select
employee0_.ID as ID1_1_,
employee0_.NAME as NAME2_1_,
employee0_.SALARY as SALARY3_1_,
employee0_.EMAIL as EMAIL4_1_,
employee0_.DEPARTMENT_ID as DEPARTME5_1_
from
DX_EMPLOYEE employee0_ limit ?
10
[Employee [id=1, name=tommy0, salary=0.0, email=tommy0@dx.com]
, Employee [id=2, name=tommy1, salary=1000.0, email=tommy1@dx.com]
, Employee [id=3, name=tommy2, salary=2000.0, email=tommy2@dx.com]
, Employee [id=4, name=tommy3, salary=3000.0, email=tommy3@dx.com]
, Employee [id=5, name=tommy4, salary=4000.0, email=tommy4@dx.com]
, Employee [id=6, name=tommy5, salary=5000.0, email=tommy5@dx.com]
, Employee [id=7, name=tommy6, salary=6000.0, email=tommy6@dx.com]
, Employee [id=8, name=tommy7, salary=7000.0, email=tommy7@dx.com]
, Employee [id=9, name=tommy8, salary=8000.0, email=tommy8@dx.com]
, Employee [id=10, name=tommy9, salary=9000.0, email=tommy9@dx.com]
]

HQL命名语句查询

在映射文件中定义命名查询语句:

1)Hibernate允许在映射文件中定义字符串形式的查询语句;

2)<query>元素用于定义一个HQL查询语句,它和<class>元素并列;

 <query name="findNewsByContent">
<![CDATA[From News n Where n.content like :keyword]]>
</query>

3)在程序中,通过Session的getNamedQuery()方法获取查询语句对应的Query对象。

修改Employee.hbm.xml

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.dx.hibernate09.hql01.Employee" table="DX_EMPLOYEE">
。。。
</class>
<query name="queryWithSalaryScope">
<![CDATA[From Employee e Where e.salary>:minSalary and e.salary<:maxSalary]]>
</query>

</hibernate-mapping>

测试函数

     @Test
public void testHQLPageQuery() {
String hql = "From Employee"; int pageNum = 1;
int pageSize = 10;
Query query = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}

执行sql及结果

 Hibernate:
select
employee0_.ID as ID1_1_,
employee0_.NAME as NAME2_1_,
employee0_.SALARY as SALARY3_1_,
employee0_.EMAIL as EMAIL4_1_,
employee0_.DEPARTMENT_ID as DEPARTME5_1_
from
DX_EMPLOYEE employee0_
where
employee0_.SALARY>?
and employee0_.SALARY<?
4
[Employee [id=7, name=tommy6, salary=6000.0, email=tommy6@dx.com]
, Employee [id=8, name=tommy7, salary=7000.0, email=tommy7@dx.com]
, Employee [id=9, name=tommy8, salary=8000.0, email=tommy8@dx.com]
, Employee [id=10, name=tommy9, salary=9000.0, email=tommy9@dx.com]
]

HQL投影查询

1)投影查询:查询结果仅包含实体的部分属性。通过SELECT关键字实现。

2)Query的list()方法返回的结果集中包含的是数组类型的元素,每个对象数组代表查询结果的一条记录。

3)可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,是程序代码能完成运用面向对象的语义来访问查询结果集。

4)可以通过DISTINCT关键字来保证查询结果不会返回重复元素。

返回数据测试:

     @Test
public void testHQLFileds() {
String hql = "Select e.email,e.salary,e.department From Employee e Where e.salary>:salary and e.department=:department";
Department department = new Department();
department.setId(3);
Query query = session.createQuery(hql).setFloat("salary", 10000).setEntity("department", department); List<Object[]> result = query.list(); for (Object[] item : result) {
System.err.println(Arrays.asList(item));
}
}

执行sql语句及结果:

 Hibernate:
select
employee0_.EMAIL as col_0_0_,
employee0_.SALARY as col_1_0_,
employee0_.DEPARTMENT_ID as col_2_0_,
department1_.ID as ID1_0_,
department1_.NAME as NAME2_0_
from
DX_EMPLOYEE employee0_
inner join
DX_DEPARTMENT department1_
on employee0_.DEPARTMENT_ID=department1_.ID
where
employee0_.SALARY>?
and employee0_.DEPARTMENT_ID=?
[tommy12@dx.com, 12000.0, Department [id=3, name=业务部门]]
[tommy17@dx.com, 17000.0, Department [id=3, name=业务部门]]
[tommy22@dx.com, 22000.0, Department [id=3, name=业务部门]]
[tommy27@dx.com, 27000.0, Department [id=3, name=业务部门]]
[tommy32@dx.com, 32000.0, Department [id=3, name=业务部门]]
[tommy37@dx.com, 37000.0, Department [id=3, name=业务部门]]
[tommy42@dx.com, 42000.0, Department [id=3, name=业务部门]]
[tommy47@dx.com, 47000.0, Department [id=3, name=业务部门]]
[tommy52@dx.com, 52000.0, Department [id=3, name=业务部门]]
[tommy57@dx.com, 57000.0, Department [id=3, name=业务部门]]
[tommy62@dx.com, 62000.0, Department [id=3, name=业务部门]]
[tommy67@dx.com, 67000.0, Department [id=3, name=业务部门]]
[tommy72@dx.com, 72000.0, Department [id=3, name=业务部门]]
[tommy77@dx.com, 77000.0, Department [id=3, name=业务部门]]

上边我们看到如果返回数据,用起来多少会有点不爽,是可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,是程序代码能完成运用面向对象的语义来访问查询结果集。

修改上边的代码:

     @Test
public void testHQLFileds_() {
String hql = "Select new Employee(e.email,e.salary,e.department) From Employee e Where e.salary>:salary and e.department=:department";
Department department = new Department();
department.setId(3);
Query query = session.createQuery(hql).setFloat("salary", 10000).setEntity("department", department); List<Employee> result = query.list(); for (Employee item : result) {
System.err.println(item.getId() + "," + item.getEmail() + "," + item.getSalary() + "," + item.getDepartment());
}
}

执行sql及结果:

 Hibernate:
select
employee0_.EMAIL as col_0_0_,
employee0_.SALARY as col_1_0_,
employee0_.DEPARTMENT_ID as col_2_0_
from
DX_EMPLOYEE employee0_
inner join
DX_DEPARTMENT department1_
on employee0_.DEPARTMENT_ID=department1_.ID
where
employee0_.SALARY>?
and employee0_.DEPARTMENT_ID=?
Hibernate:
select
department0_.ID as ID1_0_0_,
department0_.NAME as NAME2_0_0_
from
DX_DEPARTMENT department0_
where
department0_.ID=?
null,tommy12@dx.com,12000.0,Department [id=3, name=业务部门]
null,tommy17@dx.com,17000.0,Department [id=3, name=业务部门]
null,tommy22@dx.com,22000.0,Department [id=3, name=业务部门]
null,tommy27@dx.com,27000.0,Department [id=3, name=业务部门]
null,tommy32@dx.com,32000.0,Department [id=3, name=业务部门]
null,tommy37@dx.com,37000.0,Department [id=3, name=业务部门]
null,tommy42@dx.com,42000.0,Department [id=3, name=业务部门]
null,tommy47@dx.com,47000.0,Department [id=3, name=业务部门]
null,tommy52@dx.com,52000.0,Department [id=3, name=业务部门]
null,tommy57@dx.com,57000.0,Department [id=3, name=业务部门]
null,tommy62@dx.com,62000.0,Department [id=3, name=业务部门]
null,tommy67@dx.com,67000.0,Department [id=3, name=业务部门]
null,tommy72@dx.com,72000.0,Department [id=3, name=业务部门]
null,tommy77@dx.com,77000.0,Department [id=3, name=业务部门]

HQL报表查询

报表查询用于对数据分组和统计,与SQL一样,HQL利用GROUP BY关键字对数据分组,用HAVING关键字对分组数据设定约束条件。

在HQL查询语句中可以调用以下聚合函数:

  1. count()
  2. min()
  3. max()
  4. sum()
  5. avg()

测试代码

    @Test
public void testGroupBy() {
String hql = "Select min(e.salary),max(e.salary) "
+ "From Employee e "
+ "group by e.department having(min(e.salary)>:minSalary)";
Query query = session.createQuery(hql).setFloat("minSalary", 0); List<Object[]> result = query.list();
for (Object[] item : result) {
System.out.println(Arrays.asList(item));
}
}

执行sql与结果

 Hibernate:
select
min(employee0_.SALARY) as col_0_0_,
max(employee0_.SALARY) as col_1_0_
from
DX_EMPLOYEE employee0_
group by
employee0_.DEPARTMENT_ID
having
min(employee0_.SALARY)>?
[1000.0, 76000.0]
[2000.0, 77000.0]
[3000.0, 78000.0]
[4000.0, 79000.0]

Hibernate(十三):HQL查询(二)的更多相关文章

  1. Hibernate(十)HQL查询二

    一.数据库的emp名和dept表 建立持久化类和配置文件,可以用MyEclipse直接生成 持久化类 package entity; import java.util.Date; public cla ...

  2. Hibernate之HQL查询

    一.Hibernate 提供了以下几种检索对象的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 OID 检索方式: 按照对象的 OID 来检索对象 HQL 检索方式:使用面向对象的 H ...

  3. Hibernate五 HQL查询

    HQL查询一 介绍1.HQL:Hibernate Query Language,是一种完全面向对象的查询语言.使用Hibernate有多重查询方式可供选择:hibernate的HQL查询,也可以使用条 ...

  4. hibernate的hql查询

    1.概念介绍 1.Query是Hibernate的查询接口,用于从数据存储源查询对象及控制执行查询的过程,Query包装了一个HQL查询语句. 2.HQL是Hibernate Query Langua ...

  5. Hibernate 的hql查询简介【申明:来源于网络】

    Hibernate 的hql查询简介[申明:来源于网络] Hibernate 的hql查询简介:http://blog.csdn.net/leaf_130/article/details/539329 ...

  6. Hibernate(十三)命名查询-批量处理和调用存储过程

    一.命名查询 HQL语句混杂在代码之间将破坏代码的可读性 Hibernate允许在映射配置文件中定义字符串形式的查询语句,这种查询方式称为命名查询 二.建立数据表和持久化类 建立数据表 create ...

  7. Hibernate(九)HQL查询

    一.Hibernate提供的查询方式 OID查询方式:主键查询.通过get()或者load()方法加载指定OID的对象查询结果为一个 HQL查询方式:通过Query接口使用HQL语言进行查询 QBC查 ...

  8. Hibernate 笔记 HQL查询 条件查询,聚集函数,子查询,导航查询

    在hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题? 解决方案一,按照Object[]数据取出数据,然后自己组bean 解决方 ...

  9. hibernate的hql查询语句总结

    这篇随笔将会记录hql的常用的查询语句,为日后查看提供便利. 在这里通过定义了三个类,Special.Classroom.Student来做测试,Special与Classroom是一对多,Class ...

  10. Hibernate 、Hql查询和Criteria查询

    HQL查询: public Object query(String name){ Session s=null; try{ s=HibernateSessionFactory.getSession() ...

随机推荐

  1. 1-3 hibernate核心对象关系映射 xxx.hbm.xml

    详见  http://www.cnblogs.com/biehongli/p/6532800.html 1 <?xml version="1.0" encoding='utf ...

  2. Java IO流简介

    Java中的流是什么? java中的流是一个抽象的概念,在java的程序中需要把文件从一个设备传输到另一个设备上,这个设备可以是内存,程序,文件,网络.把在这些之间传输的叫做流.官方的解释:流是一组有 ...

  3. 制作Linux登录欢迎界面

    1.登录提示语: 将提示语写入/etc/motd 文件 _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ ...

  4. c++ --> 你可能不知道的c++

    你可能不知道的c++ 你可能不知道的 C++(一) 你可能不知道的 C++(二)

  5. Tram

    Tram 题目大意:给你一个图,这个图上有n点和边.点上有开关,开关开始指向一条道路,拨动开关可以使开关指向由开关出发的任意一条路径,读入,a,b,求,至少要拨动几次才能从a点走到b点. 注释:n&l ...

  6. 腾讯云python网站开发环境搭建

    前段时间腾讯云做活动,于是就花了几百大洋买了三年的云服务,准备在上 面安装python web的开发环境,下面将安装过程做一个总结,希望能够帮助大家. 一.使用环境   使用的软件环境为:CentOS ...

  7. JavaScript(第二十五天)【事件绑定及深入】

    事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型),一种是现代事件绑定(DOM2级模型).现代事件绑定在传统绑定上提供了更强大更方便的功能.   一.传统事件绑定的问题 传统事件绑定有内联模型 ...

  8. 201621123050 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现 ...

  9. 冲刺NO.10

    Alpha冲刺第十天 站立式会议 项目进展 项目核心功能逐步构建完成,测试工作也已开始.主要对部分功能组合进行测试以测试系统可用性. 问题困难 项目的主要困难在这个时间点主要存在于测试工作中,测试工作 ...

  10. C语言——第一次作业(2)

    1.写程序证明p++等价于(p)++还是等价于*(p++)? #include <stdio.h> int main() { int *p,a=5; p = &a; printf( ...