概述

•Hibernate 提供了以下几种检索对象的方式
  –导航对象图检索方式:  根据已经加载的对象导航到其他对象
  –OID 检索方式:  按照对象的 OID 来检索对象
  –HQL 检索方式: 使用面向对象的 HQL 查询语言
  –QBC 检索方式: 使用 QBC(Query By Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句, 提供了更加面向对象的查询接口.
  –本地 SQL 检索方式: 使用本地数据库的 SQL 查询语句

HQL 检索方式

  HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式.

•HQL 检索方式包括以下步骤:

  –通过 Session 的 createQuery() 方法创建一个 Query 对象, 它包括一个 HQL 查询语句. HQL 查询语句中可以包含命名参数
  –动态绑定参数
  –调用 Query 相关方法执行查询语句.

•Qurey 接口支持方法链编程风格, 它的 setXxx() 方法返回自身实例, 而不是 void 类型

•HQL vs SQL:

  –HQL 查询语句是面向对象的, Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句. HQL 查询语句中的主体是域模型中的类及类的属性
  –SQL 查询语句是与关系数据库绑定在一起的. SQL 查询语句中的主体是数据库表及表的字段.

•绑定参数:

  –Hibernate 的参数绑定机制依赖于 JDBC API 中的 PreparedStatement 的预定义 SQL 语句功能.

  –HQL 的参数绑定由两种形式:

    •按参数名字绑定: 在 HQL 查询语句中定义命名参数, 命名参数以 “:” 开头.
    •按参数位置绑定: 在 HQL 查询语句中用 “?” 来定义参数位置
  –相关方法:
    •setEntity(): 把参数与一个持久化类绑定
    •setParameter(): 绑定任意类型的参数. 该方法的第三个参数显式指定 Hibernate 映射类型

•HQL 采用 ORDER BY 关键字对查询结果排序

     public void testHQL(){
//1. 创建 Query 对象
//基于位置的参数.
String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND e.dept = ? "
+ "ORDER BY e.salary";
Query query = session.createQuery(hql); //2. 绑定参数
//Query 对象调用 setXxx 方法支持方法链的编程风格.
Department dept = new Department();
dept.setId(80);
query.setFloat(0, 6000)
.setString(1, "%A%")
.setEntity(2, dept); //3. 执行查询
List<Employee> emps = query.list();
System.out.println(emps.size());
}

testHQL1

     public void testHQLNamedParameter(){
//1. 创建 Query 对象
//基于命名参数.
String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";
Query query = session.createQuery(hql); //2. 绑定参数
query.setFloat("sal", 7000)
.setString("email", "%A%"); //3. 执行查询
List<Employee> emps = query.list();
System.out.println(emps.size());
}

testHQL2

•分页查询:

  –setFirstResult(int firstResult): 设定从哪一个对象开始检索, 参数 firstResult 表示这个对象在查询结果中的索引位置, 索引位置的起始值为 0. 默认情况下, Query 从查询结果中的第一个对象开始检索
  –setMaxResults(int maxResults): 设定一次最多检索出的对象的数目. 在默认情况下, Query 和 Criteria 接口检索出查询结果中所有的对象
     public void testPageQuery(){
String hql = "FROM Employee";
Query query = session.createQuery(hql); int pageNo = 22;
int pageSize = 5; List<Employee> emps =query.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
System.out.println(emps);
}

testPageQuery

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

  –Hibernate 允许在映射文件中定义字符串形式的查询语句.
  –<query> 元素用于定义一个 HQL 查询语句, 它和 <class> 元素并列.

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

    <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
     public void testNamedQuery(){
Query query = session.getNamedQuery("salaryEmps"); List<Employee> emps = query.setFloat("minSal", 5000)
.setFloat("maxSal", 10000)
.list(); System.out.println(emps.size());
}

testNamedQuery

投影查询

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

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

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

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

     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<Object[]> result = query.setEntity("dept", dept)
.list(); for(Object [] objs: result){
System.out.println(Arrays.asList(objs));
}
}

testFieldQuery

     public void testFieldQuery2(){
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());
}
}

testFieldQuery2

报表查询

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

•在 HQL 查询语句中可以调用以下聚集函数

  count(); min(); max(); sum(); avg()
     public void testGroupBy(){
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));
}
}

testGroupBy

HQL (迫切)左外连接

•迫切左外连接:

  –LEFT JOIN FETCH 关键字表示迫切左外连接检索策略.
  –list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee  集合都被初始化, 存放所有关联的 Employee 的实体对象.
  –查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素

•左外连接:

  –LEFT JOIN 关键字表示左外连接查询.
  –list() 方法返回的集合中存放的是对象数组类型
  –根据配置文件来决定 Employee 集合的检索策略.
  –如果希望 list() 方法返回的集合中仅包含 Department 对象, 可以在HQL 查询语句中使用 SELECT 关键字
     public void testLeftJoinFetch(){
// String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps";
String hql = "FROM Department d LEFT JOIN FETCH d.emps";
Query query = session.createQuery(hql); List<Department> depts = query.list();
depts = new ArrayList<>(new LinkedHashSet(depts));
System.out.println(depts.size()); for(Department dept: depts){
System.out.println(dept.getName() + "-" + dept.getEmps().size());
}
}

testLeftJoinFetch

HQL (迫切)内连接

•迫切内连接:

  –INNER JOIN FETCH 关键字表示迫切内连接, 也可以省略 INNER 关键字
  –list() 方法返回的集合中存放 Department 对象的引用, 每个 Department 对象的 Employee 集合都被初始化, 存放所有关联的 Employee 对象

•内连接:

  –INNER JOIN 关键字表示内连接, 也可以省略 INNER 关键字
  –list() 方法的集合中存放的每个元素对应查询结果的一条记录, 每个元素都是对象数组类型
  –如果希望 list() 方法的返回的集合仅包含 Department  对象, 可以在 HQL 查询语句中使用 SELECT 关键字

关联级别运行时的检索策略

•如果在 HQL 中没有显式指定检索策略, 将使用映射文件配置的检索策略.

•HQL 会忽略映射文件中设置的迫切左外连接检索策略, 如果希望 HQL 采用迫切左外连接策略, 就必须在 HQL 查询语句中显式的指定它

QBC 检索和本地 SQL 检索

•QBC 查询就是通过使用 Hibernate 提供的 Query By Criteria API 来查询对象,这种 API 封装了 SQL 语句的动态拼装,对查询提供了更加面向对象的功能接口

•本地SQL查询来完善HQL不能涵盖所有的查询特性

     public void testQBC(){
//1. 创建一个 Criteria 对象
Criteria criteria = session.createCriteria(Employee.class); //2. 添加查询条件: 在 QBC 中查询条件使用 Criterion 来表示
//Criterion 可以通过 Restrictions 的静态方法得到
criteria.add(Restrictions.eq("email", "SKUMAR"));
criteria.add(Restrictions.gt("salary", 5000F)); //3. 执行查询
Employee employee = (Employee) criteria.uniqueResult();
System.out.println(employee);
}

testQBC1

     public void testQBC2(){
Criteria criteria = session.createCriteria(Employee.class); //1. AND: 使用 Conjunction 表示
//Conjunction 本身就是一个 Criterion 对象
//且其中还可以添加 Criterion 对象
Conjunction conjunction = Restrictions.conjunction();
conjunction.add(Restrictions.like("name", "a", MatchMode.ANYWHERE));
Department dept = new Department();
dept.setId(80);
conjunction.add(Restrictions.eq("dept", dept));
System.out.println(conjunction); //2. OR
Disjunction disjunction = Restrictions.disjunction();
disjunction.add(Restrictions.ge("salary", 6000F));
disjunction.add(Restrictions.isNull("email")); criteria.add(disjunction);
criteria.add(conjunction); criteria.list();
}

testQBC2

     public void testQBC3(){
Criteria criteria = session.createCriteria(Employee.class); //统计查询: 使用 Projection 来表示: 可以由 Projections 的静态方法得到
criteria.setProjection(Projections.max("salary")); System.out.println(criteria.uniqueResult());
}

testQBC3

     public void testQBC4(){
Criteria criteria = session.createCriteria(Employee.class); //1. 添加排序
criteria.addOrder(Order.asc("salary"));
criteria.addOrder(Order.desc("email")); //2. 添加翻页方法
int pageSize = 5;
int pageNo = 3;
criteria.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}

testQBC4

     public void testNativeSQL(){
String sql = "INSERT INTO gg_department VALUES(?, ?)";
Query query = session.createSQLQuery(sql); query.setInteger(0, 280)
.setString(1, "ATGUIGU")
.executeUpdate();
}

testNativeSQL

Hibernate 检索方式的更多相关文章

  1. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

  2. (转) Hibernate检索方式概述

    http://blog.csdn.net/yerenyuan_pku/article/details/70554816 Hibernate检索方式概述 我们在对数据库的操作中,最常用的是select, ...

  3. hibernate检索方式(HQL 检索方式,QBC 检索方式,本地 SQL 检索方式)

    hibernate有五种检索方式,这儿用 单向的一对多的映射关系 例子,这儿有后三种的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 OID 检索方式: 按照对象的 OID 来检索对象 ...

  4. [原创]java WEB学习笔记89:Hibernate学习之路-- -Hibernate检索方式(5种),HQL介绍,实现功能,实现步骤,

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. Hibernate检索方式 分类: SSH框架 2015-07-10 22:10 4人阅读 评论(0) 收藏

    我们在项目应用中对数据进行最多的操作就是查询,数据的查询在所有ORM框架中也占有极其重要的地位.那么,如何利用Hibernate查询数据呢?Hibernate为我们提供了多种数据查询的方式,又称为Hi ...

  6. Hibernate 检索方式之 HQL 检索方式

    HQL(Hibernate Query Language) 是面向对象的查询语言,它和 SQL 查询语言有些相似.在 Hibernate 提供的各种检索方式中,HQL 是使用最广的一种检索方式,它有如 ...

  7. Hibernate -- 检索方式 HQL

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

  8. Hibernate检索方式(转载)

    我们在项目应用中对数据进行最多的操作就是查询,数据的查询在所有ORM框架中也占有极其重要的地位. 那么,如何利用Hibernate查询数据呢?Hibernate为我们提供了多种数据查询的方式,又称为H ...

  9. 7.Hibernate 检索

    1.Hibernate检索方式 检索方式简介: 导航对象图检索方式:根据已经加载的对象,导航到其他对象.OID检索方式:按照对象的OID来检索对象.Session 的 get() 和 load() 方 ...

随机推荐

  1. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数012,polygon,多边形

    <zw版·Halcon-delphi系列原创教程> Halcon分类函数012,polygon,多边形 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替换 ...

  2. 配置文件之SharedPreferences

    新建配置文件类 /** * Created by RongGuang * 应用程序配置信息 */ public class AppOption { public static final String ...

  3. 匹配所有不可见元素,或者type为hidden的元素

    查找隐藏的 tr HTML 代码: <table> <tr style="display:none"><td>Value 1</td> ...

  4. CentOS7安装Apache2.4+PHP5.6

    linux系统CentOS7 先下载Apache需要依赖的软件 1.APR 下载地址http://apr.apache.org/download.cgi wget下载路径http://mirror.b ...

  5. EasyUI中在表单提交之前进行验证

    使用EasyUi我们可以在客户端表单提交之前进行验证,过程如下:只需在onSubmit的时候使用return  $("#form1").form('validate')方法即可,E ...

  6. js 获得日期相差天数

    function getDays(strDateStart,strDateEnd){               var strSeparator = "-"; //日期分隔符   ...

  7. SC.UI

    IController using Microsoft.Practices.Prism.Events; using Microsoft.Practices.Prism.Regions; using M ...

  8. Windows下WebStorm使用SVN

    安装了phpstorm之后,想配置svn,结果在file->settings->Version Contorl->subversion->use conmand line cl ...

  9. C/C++ 宏中的 #、#@、##的作用

    宏中的# 功能是将其后面的宏参数进行字符串化操作(Stringizing operator), 简单说就是在它引用的宏变量的左右各加上一个双引号. #define STRING(x) #x 下面二条语 ...

  10. Hibernate的关联映射——双向1-N关联

    Hibernate的关联映射--双向1-N关联 对于1-N的关联,Hibernate推荐使用双向关联,而且不要让1的一端控制关联关系,而是用N的一端控制关联关系.双线的1-N关联和N-1关联是两种相同 ...