Hibernate之检索方式(HQL/QBC/本地SQL)
一、概述
Hibernate提供了以下几种检索对象的方式
导航对象图:根据已经加载的对象导航到其它对象
OID:按照对象的OID来检索对象
HQL:使用面向对象的HQL查询语句
QBC:使用QBC(Query By Criteria)API来检索对象
本地SQL:使用本地数据库的SQL查询语句
二、HQL
HQL是面向对象的查询语句,它有如下功能:
在查询语句中设定各种查询条件
支持投影查询,即仅检索出对象的部分属性
支持分页查询
支持连接查询
支持分组查询
提供内置聚集函数
支持子查询
支持动态绑定参数
能够调用用户定义的SQL函数或标准的SQL函数
步骤:
1.通过Session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句。HQL查询语句中可以包含命名参数
2.动态绑定参数
3.调用Query相关方法执行查询语句
Query接口支持方法链编程风格,它的setXxx()方法返回自身实例
绑定参数
Hibernate的参数绑定机制依赖于JDBC API中的PreparedStatement的预定义SQL语句功能
HQL的参数绑定有两种形式:
按参数名字绑定:命名参数以“:”开头
按参数位置绑定:用"?"来定义参数位置
相关方法:
setEntity():把参数与一个持久化类绑定
setParameter():绑定任意类型的参数,该方法的第三个参数显示指定Hibernate映射类型
HQL采用ORDER BY关键字对查询结果排序
实体类(对应的配置文件省略)
Department.java
public class Department {
private Integer id;private String name;private Set<Employee> emps = new HashSet<>();
}
Employee.java
public class Employee {
private Integer id;private String name;private float salary;private String email;public Employee() {}public Employee(String email, float salary, Department dept) {this.salary = salary;this.email = email;this.dept = dept;}
///get(),set()方法
}
测试:
private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}
@Testpublic 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()); }@Testpublic 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()); }
分页查询
setFirstResult(int firstResult):设定从哪一个对象开始索引(起始值为0)
setMaxResults(int maxResults):设定一次最多索引出的对象的数目
@Testpublic 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);}
在映射文件中定义命名查询语句
Hibernate允许在映射文件中定义字符串形式的查询语句
<query>元素用于定义一个HQL查询语句,它和<class>元素并列
在程序中通过Session的getNamedQuery()方法获取查询语句对应的Query对象
<query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
@Testpublic void testNamedQuery(){Query query = session.getNamedQuery("salaryEmps");List<Employee> emps = query.setFloat("minSal", 5000).setFloat("maxSal", 10000).list();System.out.println(emps.size()); }
投影查询
查询结果仅包含实体的部分属性,通过select关键字实现
list()方法返回的集合中包含的是数组类型的元素,每个对象数组代表查询结果的一条记录
可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录
可以通过distinct关键字来保证查询结果不会返回重复元素
@Testpublic 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());}}@Testpublic 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));}}
报表查询
报表查询用于对数据分组和统计
在HQL查询语句中可以调用以下聚集函数
count()
min()
max()
sum()
avg()
@Testpublic 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));}}
迫切左外连接
left join fetch关键字
list()方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee 集合都被初始化, 存放所有关联的 Employee 的实体对象
查询结果中可能会包含重复元素, 可以通过一个 HashSet 来过滤重复元素
@Testpublic void testLeftJoinFetch(){
// String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps";String hql = "FROM Department d INNER 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());}}
左外连接:
left join关键字
list()方法返回的集合中存放的是对象数组类型
根据配置文件来决定Employee集合的检索策略
如果希望list()方法返回的集合中包含Department对象,可以在HQL查询语句中使用select关键字
@Testpublic void testLeftJoin(){String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";Query query = session.createQuery(hql);List<Department> depts = query.list();System.out.println(depts.size());for(Department dept: depts){System.out.println(dept.getName() + ", " + dept.getEmps().size()); }// String hql = "FROM Department d LEFT JOIN d.emps";
// List<Object []> result = query.list();
// result = new ArrayList<>(new LinkedHashSet<>(result));
// System.out.println(result);
//
// for(Object [] objs: result){
// System.out.println(Arrays.asList(objs));
// }}
(迫切)内连接(原理同上)
@Testpublic void testLeftJoinFetch2(){String hql = "SELECT e FROM Employee e INNER JOIN 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());}}
三、QBC
QBC查询就是通过使用Hibernate提供的QBC API来查询对象
@Testpublic 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();}@Testpublic void testQBC3(){Criteria criteria = session.createCriteria(Employee.class);//统计查询: 使用 Projection 来表示: 可以由 Projections 的静态方法得到criteria.setProjection(Projections.max("salary"));System.out.println(criteria.uniqueResult()); }@Testpublic 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));//name like "%a%" and dept=Department [id=80]System.out.println(conjunction); //2. ORDisjunction disjunction = Restrictions.disjunction();disjunction.add(Restrictions.ge("salary", 6000F));disjunction.add(Restrictions.isNull("email"));//salary>=6000 or email is nullSystem.out.println(disjunction); //上述的两个条件用and连接起来criteria.add(disjunction);criteria.add(conjunction);criteria.list();}@Testpublic 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); }
四、本地SQL
@Testpublic void testNativeSQL(){String sql = "INSERT INTO gg_department VALUES(?, ?)";Query query = session.createSQLQuery(sql);query.setInteger(0, 280).setString(1, "ATGUIGU").executeUpdate();}
Hibernate之检索方式(HQL/QBC/本地SQL)相关推荐
- hibernate教程--检索方式详解(hql,sql,QBC)
1.1 Hibernate的检索方式 1.1.1 Hibernate的检索方式: 检索方式:查询的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 * Customer custome ...
- hibernate教程--检索方式(hql,sql,QBC)
1.1Hibernate的检索方式 1.1.1Hibernate的检索方式: 检索方式:查询的方式: 导航对象图检索方式: 根据已经加载的对象导航到其他对象 * Customer customer = ...
- Hibernate之检索方式
时间:2017-1-22 16:09 --检索方式 Hibernate中提供了以下几种检索对象的方式: * 导航对象图检索方式 根据已经加载额对象导航到其他对象. ...
- HIbernate的检索方式
导航对象图检索方式 根据已经加载的对象,导航到其他对象 OID检索方式 按照对象的OID来检索对象 依赖Session接口 主要是load()/get()的用法 HQL检索方式 Hibernate Q ...
- JAVAWEB开发之Hibernate详解(三)——Hibernate的检索方式、抓取策略以及利用二级缓存进行优化、解决数据库事务并发问题
Hibernate的检索方式 Hibernate提供了以下几种检索对象的方式: 导航对象图检索方式:根据已经加载的对象导航到其他对象. OID检索方式:按照对象的OID来检索对象. HQL检索方式: ...
- Hibernate 查询方式(HQL/QBC/QBE)汇总
作为老牌的 ORM 框架,Hibernate 在推动数据库持久化层所做出的贡献有目共睹. 它所提供的数据查询方式也越来越丰富,从 SQL 到自创的 HQL,再到面向对象的标准化查询. 虽然查询方式有点 ...
- Hibernate的几种查询方式 HQL,QBC,QBE,离线查询,复合查询,分页查询
HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了 ...
- Hibernate的几种查询方式-HQL,QBC,QBE,离线查询,复合查询,分页查询
HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了 ...
- Hibernate的集中查询方式 : hql查询,QBC查询和QBE查询
转载:http://blog.csdn.net/iijse/article/details/6161143 通常使用的Hibernate通常是三种:hql查询,QBC查询和QBE查询: 1.QBE( ...
最新文章
- 百度二面:一个线程OOM了,其它线程还能运行吗?
- idea怎么将本地文件和远程git对比_IntelliJ IDEA将文件和文件夹与本地版本进行比较...
- 怎么用java ee编程_Java EE应用程序入门 - 编程入门网
- 37、JAVA_WEB开发基础之上传功能
- lightgbm 数据不平衡_不平衡数据下的机器学习(下)
- java this self_[原]Javasript 关于self(that) = this用法的理解
- php实现快速排序和冒泡排序
- 【MFC开发(9)】列表控件List Box
- heidisql导入sql文件
- Cadence Allegro针对Shape进行Vertex推挤拉伸操作方法图文教程
- matlab统计像元灰度值的函数,matlab像素值及统计
- https://github.com/liuyi01/kubernetes-starterhttps://github.com/liuyi01/kubernetes-starter
- AOJ-AHU-OJ-401 Fibonacci GCD
- 云栖社区2017中国开发者调查报告
- 分子动力学及第一性原理计算
- Linux 8723be无线网卡,解决rtl8723be无线网卡驱动频繁断网问题
- 工程测量gps静态的实训报告_GPS-RTK实战攻略——静态、动态测量的区别和步骤...
- 【Unity基础知识之一】 Unity支持 IOS 64-BIT
- PySide2学习总结(十二)打开文件对话框--FileDialog
- QPluginLoader 加载插件dll失败