Hibernate中共提供了三种检索方式:HQL(Hibernate Query Language)、QBC、QBE(Query By Example)。

  HQL 是Hibernate Query Language的简写,即hibernate查询语言:HQL采用面向对象的查询方式。

  QBC(Query By Criteria) API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Expresson类组成,它支持在运行时动态生成查询语句。

  HQL 查询包括以下步骤:

  1. 获取Hibernate Session对象。
  2. 编写HQL语句
  3. 以HQL语句作为参数,调用Session的createQuery方法创建查询对象。
  4. 如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值。
  5. 调用Query对象的list()或uniqueResult()方法返回查询结果列表(持久化实体集)
  QBC检索步骤:
  1.调用Session的createCriteria()方法创建一个Criteria对象。
  2.设定查询条件。Restrictions类提供了一系列用于设定查询条件的静态方法
  这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。
  Criteria的add()方法用于加入查询条件。
  3.调用Criteria的list()方法执行查询语句。该方法返回List类型的查询结果,在
  List集合中存放了符合查询条件的持久化对象。
 
  下面列出我学习的代码。
  Department类

package oracle.hqlqbc;

import java.util.HashSet;
import java.util.Set; public class Department {
private Integer id;
private String name; private Set<Employee> emps = new HashSet<>(); public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} @Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Department [id=");
builder.append(id);
builder.append(", name=");
builder.append(name);
builder.append(", empsSize=");
builder.append(emps.size());
builder.append("]");
return builder.toString();
} public void setName(String name) {
this.name = name;
} public Set<Employee> getEmps() {
return emps;
} public void setEmps(Set<Employee> emps) {
this.emps = emps;
}
}

  Employee类

package oracle.hqlqbc;

public class Employee {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Employee [id=");
builder.append(id);
builder.append(", name=");
builder.append(name);
builder.append(", salary=");
builder.append(salary);
builder.append(", email=");
builder.append(email);
builder.append(", deptId=");
builder.append(dept.getId());
builder.append("]");
return builder.toString();
} private Integer id;
private String name;
private float salary;
private String email; private Department dept; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public float getSalary() {
return salary;
} public void setSalary(float salary) {
this.salary = salary;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public Department getDept() {
return dept;
} public void setDept(Department dept) {
this.dept = dept;
} public Employee(float salary, String email, Department dept) {
super();
this.salary = salary;
this.email = email;
this.dept = dept;
} public Employee() {
}
}

  Department.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-7-29 2:43:46 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="oracle.test">
<class name="Department" table="DEPARTMENT">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property> <set name="emps" table="EMPLOYEE" inverse="true" lazy="true">
<key><column name="DEPT_ID" /></key>
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>

  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-7-29 2:43:46 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="oracle.test">
<class name="Employee" table="EMPLOYEE">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property> <property name="salary" type="float">
<column name="SALARY" />
</property> <property name="email" type="java.lang.String">
<column name="EMAIL" />
</property> <many-to-one name="dept" class="Department" fetch="join"><!-- join select subselect-->
<column name="DEPT_ID" />
</many-to-one>
</class> <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
</hibernate-mapping>

  具体用法的例子:

package oracle.hqlqbc;

import java.util.Arrays;
import java.util.List; import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import oracle.hqlqbc.Department;
import oracle.hqlqbc.Employee; public class HibernateTest {
private SessionFactory sessionFactory; private Session session; private Transaction transaction; @Before
public void init()
{
System.out.println("init"); // 1. 创建一个SessionFactory对象
sessionFactory = null;
Configuration configuration = new Configuration().configure(); // before 4.0
// sessionFactory = configuration.buildSessionFactory(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2. 创建一个Session 对象
session = sessionFactory.openSession(); // 3. 开启事务
transaction = session.beginTransaction(); } @After
public void destory()
{
System.out.println("destory");
// 5. 提交事务
transaction.commit(); // 6. 关闭Session
session.close(); // 7. 关闭SesssionFactory
sessionFactory.close();
} @Test
public void testNamedParameter()
{
String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";
Query query = session.createQuery(hql); // 可以用命名参数
query.setFloat("sal", 7000)
.setString("email", "%A%"); List<Employee> emps = query.list();
System.out.println(emps.size());
} @Test
public void createTable()
{ } @Test
public void testHQL()
{
// 1. 创建Query对象: 可以加 ORDER BY
String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND 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%");
// 可用用实体
query.setEntity(2, dept); // 3. 执行查询
List<Employee> employees = query.list();
System.out.println(employees.size());
} /*
* 分页查询
*/
@Test
public void testPageQuery()
{
String hql = "FROM Employee";
Query query = session.createQuery(hql); int pageNo = 3;
int pageSize = 5; List<Employee> emps = query.setFirstResult((pageNo - 1)* pageSize)
.setMaxResults(pageSize).list();
System.out.println(emps);
} /*
* 命名查询
*/
@Test
public void namedQuery()
{
Query query = session.getNamedQuery("salaryEmps");
List<Employee> emps = query.setFloat("minSal", 5000)
.setFloat("maxSal", 10000)
.list();
System.out.println(emps.size());
} /*
* 投影查询1: 操作数组
*/
@Test
public void testPropertyQuery()
{
String hql = "SELECT e.email, e.salary 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));
}
} /*
* 投影查询2: 操作entity:使用构造器
*/
@Test
public void testPropertyQuery2()
{
String hql = "SELECT new Employee(e.salary, e.email, 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());
} } /*
* 报表查询: 可以使用聚合函数
*/
@Test
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", 5000);
List<Object[]> result = query.list(); for(Object[] objs: result)
{
System.out.println(Arrays.asList(objs));
}
} /*
* HQL 会忽略配置文件中的fetch=join的设置,如果想用,就在代码中直接写
* 迫切左外连接:返回department,注意去重
*/
@Test
public void testLeftJoinFetch()
{
String hql = "SELECT DISTINCT d FROM Department d INNER JOIN FETCH d.emps";
Query query = session.createQuery(hql); // 集合去重
// new ArrayList<>(new HashSet<>(Collection c)); List<Department> depts = query.list();
System.out.println(depts.size()); for(Department dept: depts)
{
System.out.println(dept.getName() + ", " + dept.getEmps().size());
}
} /*
* 默认返回对象数组,注意去重,
*/
@Test
public void testLeftJoin()
{
// 这样返回的Employee未被初始化
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql); /*List<Object[]> result = query.list();
System.out.println(result); for(Object[] objs: result)
{
System.out.println(Arrays.asList(objs));
}*/ List<Department> depts = query.list();
System.out.println(depts.size());
for(Department dept: depts)
{
System.out.println(dept.getName());
}
} @Test
public void testLeftJoinFetch2()
{
String hql = "SELECT e FROM Employee e INNER JOIN FETCH e.dept";
Query query = session.createQuery(hql); List<Employee> emps = query.list();
System.out.println(emps.size()); for(Employee emp: emps)
{
System.out.println(emp.getName() + ", " + emp.getDept().getName());
}
} @Test
public void testQBCQuery()
{
Criteria criteria = session.createCriteria(Employee.class);
criteria.add(Restrictions.eq("email", "SKUMAR"));
criteria.add(Restrictions.gt("salary", 5000f));
Employee employee = (Employee) criteria.uniqueResult();
System.out.println(employee);
} @Test
public void testQBCQuery2()
{
Criteria criteria = session.createCriteria(Employee.class);
// 1. AND: 使用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); // or
Disjunction disjunction = Restrictions.disjunction();
disjunction.add(Restrictions.ge("salary", 6000));
disjunction.add(Restrictions.isNotNull("email"));
criteria.add(conjunction);
criteria.add(disjunction); criteria.list();
} @Test
public void testQBCQuery3()
{
Criteria criteria = session.createCriteria(Employee.class);
// 统计查询
criteria.setProjection(Projections.max("salary")); System.out.println(criteria.uniqueResult());
} @Test
public void testQBCQuery4()
{
Criteria criteria = session.createCriteria(Employee.class);
criteria.addOrder(Order.asc("salary"));
criteria.addOrder(Order.desc("email")); int pageSize = 5;
int pageNo = 3;
criteria.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize).list();
} @Test
public void testNativeSQL()
{
String sql = "INSERT INTO department VALUES(?, ?)";
Query query = session.createSQLQuery(sql);
query.setInteger(0, 280)
.setString(1, "ATGUIGU")
.executeUpdate();
} @Test
public void testHQLUpdate()
{
String hql = "DELETE FROM Department d where d.id = :id";
session.createQuery(hql).setInteger("id", 280).executeUpdate();
}
}

  好了,例子都在上面,自己也复习了一遍,有了一个初步的印象,本文仅供入门了解,更深入的内容查看相关文章学习。

HIBERNATE知识复习记录4-HQL和QBC的更多相关文章

  1. HIBERNATE知识复习记录1-连接及常用方法

    要去面试了,复习一下HIBERNATE的相关知识吧,原来边看视频边写的代码如下,已经分不清先后次序了,大致看一看吧. 先看下总的配置文件hibernate.cfg.xml: <?xml vers ...

  2. HIBERNATE知识复习记录3-关联关系

    先上一张图,关于几种关系映射: 抄一段解释: 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用.关联关系分为上述七 ...

  3. HIBERNATE知识复习记录2-继承关系

    发现了一篇和我类似的学习尚硅谷视频写的文章,内容如下,比我说的详细全面,可以看一下: [原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , jo ...

  4. Hibernate —— HQL、QBC检索方式

    一.HQL 检索方式 以双向的一对多来测试 HQL 检索方式.以 Department 和 Employee 为例. 建表语句: CREATE TABLE department ( dept_id ) ...

  5. Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)

    1.非集成Spring hibernate的检索方式,主要有以下五种. 1.导航对象图检索方式.(根据已经加载的对象,导航到其他对象.) 2.OID检索方式.(按照对象的OID来检索对象.) 3.HQ ...

  6. Hibernate 知识收纳.

     一.乐观锁和悲观锁 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿 ...

  7. PE知识复习之PE的重定位表

    PE知识复习之PE的重定位表 一丶何为重定位 重定位的意思就是修正偏移的意思.  如一个地址位 0x401234 ,Imagebase = 0x400000 . 那么RVA就是 1234.  如果Im ...

  8. PE知识复习之PE的导入表

    PE知识复习之PE的导入表 一丶简介 上一讲讲解了导出表. 也就是一个PE文件给别人使用的时候.导出的函数  函数的地址 函数名称 序号 等等. 一个进程是一组PE文件构成的.  PE文件需要依赖那些 ...

  9. PE知识复习之PE的导出表

    PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就 ...

随机推荐

  1. linux中tomcat内存溢出解决办法

    用命令 tail -f /root/apache-tomcat-6.0.20/logs/catalina.out(需要找到tomcat路径) 查看日志,查看是否有错误 linux中tomcat内存溢出 ...

  2. linux日志分析

    转一位大神的笔记. 日志管理: 1.基于服务的 2.基于时间的 /var/log/wtmp,/var/run/utmp,/var/log/lastlog(lastlog),/var/log/btmp( ...

  3. import()、import语句、require() 区别

    import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载. import() 与 import语句 区别 区别项 import() import语句 参数都 ...

  4. 阿里巴巴Java开发手册-并发处理

    1. [强制]获取单例对象需要保证线程安全,其中的方法也要保证线程安全.说明:资源驱动类.工具类.单例工厂类都需要注意. 2. [强制]创建线程或线程池时请指定有意义的线程名称,方便出错时回溯.正例: ...

  5. [C++ Primer] : 第16章: 模板与泛型编程

    面向对象编程(OOP)和泛型编程都能处理在编写程序时不知道类型的情况, 不同之处在于: OOP能处理类型在程序运行之前都未知的情况, 而在泛型编程中, 在编译时就能获知类型了. 函数模板 模板是C++ ...

  6. android自定义控件的一个思路-入门

    转自:http://blog.sina.com.cn/s/blog_691051e10101a3by.html   很多时候没有我们需要使用的控件,或者控件并不美观.比如这个滑动开关,这是androi ...

  7. 纯文本文件 student.txt为学生信息, 里面的内容(包括花括号)如下所示

    import json from collections import OrderedDict import xlwt with open('student.txt',encoding='utf-8' ...

  8. Spring 注解方式 实现 IOC 和 DI

    注:以下所有测试案例(最后一个除外)的测试代码都是同一个: package cn.tedu.test; import org.junit.Test; import org.springframewor ...

  9. HDU 2066 一个人的旅行 (Dijkstra算法)

    一个人的旅行 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submis ...

  10. 1042 Shuffling Machine (20 分)

    1042 Shuffling Machine (20 分) Shuffling is a procedure used to randomize a deck of playing cards. Be ...