HIBERNATE知识复习记录4-HQL和QBC
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 查询包括以下步骤:
- 获取Hibernate Session对象。
- 编写HQL语句
- 以HQL语句作为参数,调用Session的createQuery方法创建查询对象。
- 如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值。
- 调用Query对象的list()或uniqueResult()方法返回查询结果列表(持久化实体集)
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的更多相关文章
- HIBERNATE知识复习记录1-连接及常用方法
要去面试了,复习一下HIBERNATE的相关知识吧,原来边看视频边写的代码如下,已经分不清先后次序了,大致看一看吧. 先看下总的配置文件hibernate.cfg.xml: <?xml vers ...
- HIBERNATE知识复习记录3-关联关系
先上一张图,关于几种关系映射: 抄一段解释: 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用.关联关系分为上述七 ...
- HIBERNATE知识复习记录2-继承关系
发现了一篇和我类似的学习尚硅谷视频写的文章,内容如下,比我说的详细全面,可以看一下: [原创]java WEB学习笔记87:Hibernate学习之路-- -映射 继承关系(subclass , jo ...
- Hibernate —— HQL、QBC检索方式
一.HQL 检索方式 以双向的一对多来测试 HQL 检索方式.以 Department 和 Employee 为例. 建表语句: CREATE TABLE department ( dept_id ) ...
- Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)
1.非集成Spring hibernate的检索方式,主要有以下五种. 1.导航对象图检索方式.(根据已经加载的对象,导航到其他对象.) 2.OID检索方式.(按照对象的OID来检索对象.) 3.HQ ...
- Hibernate 知识收纳.
一.乐观锁和悲观锁 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿 ...
- PE知识复习之PE的重定位表
PE知识复习之PE的重定位表 一丶何为重定位 重定位的意思就是修正偏移的意思. 如一个地址位 0x401234 ,Imagebase = 0x400000 . 那么RVA就是 1234. 如果Im ...
- PE知识复习之PE的导入表
PE知识复习之PE的导入表 一丶简介 上一讲讲解了导出表. 也就是一个PE文件给别人使用的时候.导出的函数 函数的地址 函数名称 序号 等等. 一个进程是一组PE文件构成的. PE文件需要依赖那些 ...
- PE知识复习之PE的导出表
PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就 ...
随机推荐
- Oracle DataBase单实例使用ASM案例(1)--ASM基本概念
版权声明:本文为博主原创文章,未经博主允许不得转载. Oracle DataBase单实例使用ASM案例(1)--ASM基本概念 系统环境: 操作系统:RH EL5-64 Oracle 软件: Ora ...
- JUC线程池之 线程池架构
线程池的架构图如下: Executor 它是"执行者"接口,它是来执行任务的.准确的说,Executor提供了execute()接口来执行已提交的 Runnable 任务的对象.E ...
- java 中一些需要注意的知识点
java数组的length属性是容量,而不是数组真实元素的个数: 多线程中的interrupt()方法并不会终止处于"运行状态"的线程,它只是将线程的中断标记设为true. juc ...
- AppBox Mvc数据库初始化
下载AppBoxMvc后,以为CTRL_F5运行后就能数据库初始化了.一直报失败 我的环境是VS2017,利用VS2017自带的数据库 后修改: 1. 修改AppBoxContext.cs publ ...
- bzoj 4484 [Jsoi2015]最小表示——bitset
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4484 每个点上存一下它到每个点的连通性.用 bitset 的话空间就是 \( \frac{n ...
- R(2) sample
sample: 从整体中挑出部分样本数据函数 Usage: sample.int(n, size = n, replace = FALSE, prob = NULL) x:可以是R中任何对象 siz ...
- each与list的用法(PHP学习)
1.each的用法 先看API array each ( array &$array ) api里是这么描述的:each — 返回数组中当前的键/值对并将数组指针向前移动一步 我们先来看看返回 ...
- 修改phpMYadmin 链接其他数据库地址的方法
找到phpmyadmin的文件 修改 config.inc.php 文件 框红的地方修改成你需要链接的数据库信息 重启环境,再次访问 phpmyadmin 地址即可
- Bootstrap:教程、简介、环境安装
ylbtech-Bootstrap:教程.简介.环境安装 1. Bootstrap 教程返回顶部 1. Bootstrap 教程 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.B ...
- 自绘图片下拉项 combobox listbox
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...