Hibernate 的查询
1. Hibernate 框架的查询方式
- 唯一标识OID的检索方式:
session.get(对象.class, OID)
- 对象导航的方式;
- HQL 检索方式;
- QBC 检索方式;
- SQL 检索方式
2. HQL 检索方式
2.1 HQL 与 SQL 的关系
- HQL: Hibernate Query Language; 使用的是 Query 接口;
- HQL 查询语句是面向对象的. Hibernate 负责解析 HQL 查询语句,然后根据对象-关系映射文件中的映射信息,把 HQL
查询语句翻译成相应的 SQL 语句; - HQL 查询语句中的主体是域模型中的类及类的属性;
- SQL 查询语句中的主体是数据库表及表的字段;
2.2 HQL 查询所有
// 查询所有客户
// 第一种方式:
// 创建 HQL 的查询接口(即 Query 接口)
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
// 第二种方式: 方法链
List<Customer> list = session.createQuery("from Customer").list();
// 第三种方式: 使用别名的方式
List<Customer> list = session.createQuery("from Customer c").list();
List<Customer> list = session.createQuery("select c from Customer c").list();
2.3 HQL 条件查询
// 第一种方式:
Query query = session.createQuery("from Customer where name=?");
query.setString(0,"张三"); // 给第一个问号赋值
List<Customer> list = query.list();
// 第二种方式:
Query query = session.createQuery("from Customer where name= :aaa and age= :bbb");
query.setString("aaa","张三");
query.setInteger("bbb",39);
List<Customer> list = query.list();
// 第三种方式:
Query query = session.createQuery("from Customer where name=?");
query.setParameter(0,"张三"); // "setParameter" 不用考虑参数的具体类型;
2.4 HQL 排序查询
// 升序
session.createQuery("from Customer order by cust_id").list();
// 降序
session.createQuery("from Customer order by cust_id desc").list();
2.5 HQL 分页查询
// Hibernate 框架提供了关于分页的两个方法
// setFirstResult(a) : 从哪条记录开始,如果查询是从第一条记录开始, 值是 0;
// setMaxResults(b) : 每页查询的记录条数;
List<LinkMan> list = session.creatQuery("from Customer").setFirstResult(0)
.setMaxResults(10).list();
2.6 HQL 投影查询
- 投影查询就是想查询某一字段或某几个字段的值;
// 需求: 查询多个字段
// 第一种方式: 返回的是由这几个字段组成的数组
List<Object[]> list = session.createQuery("select c.cust_name,c.cust_level from Customer c").list();
for(Object[] objects : list){
System.out.println(Arrays.toString(objects));
}
// 第二种方式: 返回只有这几个字段组成的对象
// 1. 需要先在持久化类中提供对应字段的有参构造方法;
// 2. 通过 new 将多个字段封装到对象中, 进行查询;
public class Customer{
private String cust_name;
private Integer cust_age;
private String cust_level;
...
// 有参构造方法
public Customer(String cust_name, String cust_level){
this.cust_name = cust_name;
this.cust_level = cust_level;
}
// 保留空的构造方法
public Customer(){
super();
}
.....get 和 set 方法
}
List<Customer> list = session.createQuery("select
new Customer(c.cust_name, c.cust_level) from Customer c").list();
for(Customer customer : list){
System.out.println(customer);
}
2.7 HQL 聚合函数
count()
sum()
avg()
min()
max()
// 1. 获取总的记录数
// List<Number> list = session.createQuery("select count(*) from Customer").list();
List<Number> list = session.createQuery("select count(c) from Customer c").list();
Long count = list.get(0).longValue();
System.out.println(count);
// 2. 获取某一列数据的和
List<Number> list = session.createQuery("select sum(c.cust_id) from Customer c").list();
Long count = list.get(0).longValue();
System.out.println(count);
3. QBC 检索方式
3.1 QBC 概述
- QBC,Query By Criteria, 使用 Criteria 接口;
- 完全面向对象;
- 非常适合做条件查询;
3.2 QBC 查询所有
// 查询所有记录
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
3.3 排序查询
- 使用
addOrder()
方法来设置参数;org.hibernate.criterion.Order
包
Criteria criteria = session.createCriteria(Customer.class);
// 设置为降序
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();
3.4 分页查询
setFirstResult()
setMaxResults()
Criteria criteria = session.createCriteria(Customer.class);
// 设置为降序
criteria.addOrder(Order.desc("cust_id"));
// 设置分页的方法
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List<Customer> list = criteria.list();
3.5 QBC 条件查询
- 条件查询使用 Criteria 接口的 add 方法,用来传入条件;
- Criterion 接口,表示查询的条件;
- Restrictions 类是 Hibernate 框架提供的工具类,不是 Criterion 接口的实现类;用来设置查询条件;
- Restrictions 中常用方法:
eq(等于), gt(大于), lt(小于)
ge(大于等于), le(小于等于)
between
: 在...之间, 头和尾都包含;like
: 模糊查询;in
: 范围;and
: 并且;or
: 或者;isNull
: 判断值是否为空;isEmpty
: 判断关联的集合是否为空;
// 查询姓名叫"张三"的客户
Criteria criteria = session.createCriteria(Customer.class);
// 使用 Restrictions 传入条件
criteria.add(Restrictions.eq("name","张三"));
List<Customer> list = criteria.list();
// 查询姓名中包含"小"的客户(模糊查询)
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("name","%小%"));
List<Customer> list = criteria.list();
// in 方法
// Restrictions.in(String propertyName, Collection values); // 集合
// Restrictions.in(String propertyName, Object[] values); // 数组
List<Long> params = new ArrayList<Long>();
params.add(1L);
params.add(2L);
params.add(7L);
criteria.add(Restrictions.in("cust_id",params));
// or 方法, 性别为女,或者 cust_id 大于 3
criteria.add(Restrictions.or(Restrictions.eq("cust_gender","女"),Restrictions.gt("cust_id",3L)));
3.6 QBC 聚合函数查询
- Projections 是 Hibernate 框架的工具类,用来设置聚合函数查询;
org.hibernate.criterion
包下 - 需要使用
criteria.setProjection()
来添加条件;
Criteria criteria = session.createCriteria(Customer.class);
// 设置聚合函数
criteria.setProjection(Projections.rowCount());
List<Number> list = criteria.list();
Long count = list.get(0).longValue();
// 注意问题
pubic void fun(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 创建 QBC 查询接口
Criteria criteria = session.createCriteria(Customer.class);
// 设置聚合函数
criteria.setProjection(Projections.count("cust_id"));
List<Number> list = criteria.list();
Long count = list.get(0).longValue();
// 因为此时的查询语句, 相当于 select count(cust_id) from 表
// 如果想继续查询所有客户,需要 setProjection(null);
criteria.setProjection(null);
// 继续查询所有客户
List<Customer> customers = criteria.list();
for(Customer customer : customers){
System.out.println(customer);
}
}
4. 离线条件查询
- 离线条件查询使用的是 DetachedCriteria 接口进行查询;
- 离线条件查询对象在创建的时候,不需要使用 session 对象, 只是在查询的时候,使用 session 对象;
- 可以在 WEB 层创建离线条件查询对象;
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 创建离线条件查询对象
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
// 设置查询条件
criteria.add(Restrictions.eq("cust_gender","男"));
// 查询数据, 需要使用 session
List<Customer> list = criteria.getExecutableCriteria(session).list();
for(Customer customer : list){
System.out.println(customer);
}
tr.commit();
5. SQL 查询方式(了解)
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("select * from cust_customer where cust_gender = ?");
sqlQuery.setParameter(0,"男");
// 将返回结果(是List<Object[]> 类型), 封装到对象中
sqlQuery.addEntity(Customer.class);
List<Customer> list = sqlQuery.list();
for(Customer customer : list){
System.out.println(customer);
}
tr.commit();
6. HQL 多表查询
6.1 SQL 的多表查询
// 内连接查询
// 显示内连接
select * from customer c inner join orders o on c.cid = o.cno;
// 隐式内连接
select * from customer c, orders o where c.cid = o.cno;
// 外连接
// 左外连接
select * from customer c left outer join orders o on c.cid = o.cno;
// 右外连接
select * from customer c right outer join orders o on c.cid = o.cno;
6.2 HQL 的多表查询
- 非迫切连接: 返回的结果是 Object[];
- 迫切连接: 返回的结果是对象,
// 使用内连接查询,默认返回的是 Object 数组
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
List<Object[]> list = session.createQuery("from Customer c inner join c.linkmans").list();
for(Object[] objects : list){
System.out.println(Arrays.toString(objects));
}
// 使用 fetch 关键字, 会把返回结果封装到对象中
// fetch 迫切连接
List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
for(Customer customer : list){
System.out.println(customer);
}
// 解决数据重复的问题, 因为 Customer 对象中存在 Set<Linkman> linkmans 集合
// 所以返回的结果, 一个联系人对应一个客户.
// 需要的结果: 一个客户中存在n个联系人. 自己手动 new Set 集合
List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
Set<Customer> set = new HashSet<Customer>(list);
for(Customer customer : set){
System.out.println(customer);
}
// 迫切左外连接
List<Customer> list = session.createQuery("from Customer c left join fetch c.linkmans").list();
7. HQL 框架之延迟加载
- 延迟加载先获取到代理对象,当真正使用到该对象中的属性的时候,才会发送 SQL 语句, 是 Hibernate 框架提升性能的方式;
- 类级别的延迟加载
- session 对象的
load()
方法就是延迟加载; Customer c = session.load(Customer.class, 1L)
没有发送 SQL 语句, 当使用该对象的属性时,才发送 SQL 语句- 使类级别的延迟加载失效(两种方法)
- 在
<class>
标签上配置lazy="false"
; - Hibernate.initialize(Object proxy);
- 在
- session 对象的
- 关联级别的延迟加载
- 查询某个客户下的所有联系人, 默认是延迟加载;
8. Hibernate 框架关联级别的查询优化策略
8.1 查询策略
- 使用 Hibernate 框架查询一个对象的时候,查询其关联对象,应该如何查询. 是 Hibernate 框架的一种优化手段;
8.2 Hibernate 框架的查询策略解决的问题
- 查询的时机
lazy
属性解决查询的时机问题,表示是否需要延迟加载;
- 查询的语句形式
fetch
属性解决查询语句的格式问题;
8.3 在 <set>
标签上使用 fetch
和 lazy
属性
fetch
的取值:select
: 默认值,发送基本select
语句查询;join
: 连接查询,发送的是一条迫切左外连接! 配置了该属性,lazy
属性就失效了;subselect
: 子查询,发送一条子查询,查询关联对象;
lazy
的取值true
: 默认延迟;false
: 不延迟;extra
: 及其懒惰;
- 总结: 开发中, 基本上使用的都是默认值:
fetch = select, lazy=true
;
8.4 在 <many-to-one>
标签上使用 fetch
和 lazy
属性
fetch
的取值select
: 默认值,发送基本select
语句查询;join
: 发送迫切左外连接查询;
lazy
的取值false
: 不采用延迟加载;proxy
: 默认值,代理;表示由另一端<class>
上的lazy
属性决定;
参考资料
Hibernate 的查询的更多相关文章
- hibernate模糊查询
hibernate模糊查询-Restrictions.ilike & Expression.like Criteria criteria = session.createCriteria(Ta ...
- Hibernate的查询方式总结
Hibernate的查询方式大体有三种,分别是HQL QBC和SQL三种.在网上查阅一一些资料,做了一个简单的总结. 1. SQL sql 是面向数据库表查询,from 后面跟的是表名,where 后 ...
- atitit。 hb Hibernate sql 查询使用
atitit. hb Hibernate sql 查询使用 #----------返回list<map>法..这个推荐使用. q.setResultTransformer(Tr ...
- Hibernate高级查询QBC条件设置——Restrictions用法 引自:http://www.cnblogs.com/evon168/archive/2010/10/29/1863059.html
方法说明 方法 说明 Restrictions.eq = Restrictions.allEq 利用Map来进行多个等于的限制 Restrictions.gt > Restrictions.ge ...
- Hibernate HQL查询:
Hibernate HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查 ...
- Hibernate HQL查询语句总结
Hibernate HQL查询语句总结 1. 实体查询:有关实体查询技术,其实我们在先前已经有多次涉及,比如下面的例子:String hql="from User user ";L ...
- Hibernate的查询,二级缓存,连接池
Hibernate的查询,二级缓存,连接池 1.Hibernate查询数据 Hibernate中的查询方法有5中: 1.1.Get/Load主键查询 使用get或者load方法来查询,两者之间的区别在 ...
- hibernate sql查询转换成VO返回list
hibernate sql查询转换成VO @Override public List<FenxiVo> getTuanDuiFenxiList(FenxiVo FenxiVo,Intege ...
- Struts2学习笔记NO.1------结合Hibernate完成查询商品类别简单案例(工具IDEA)
Struts2学习笔记一结合Hibernate完成查询商品类别简单案例(工具IDEA) 1.jar包准备 Hibernate+Struts2 jar包 struts的jar比较多,可以从Struts官 ...
- Hibernate【查询、连接池、逆向工程】
前言 在Hibernate的第二篇中只是简单地说了Hibernate的几种查询方式....到目前为止,我们都是使用一些简单的主键查询阿...使用HQL查询所有的数据....本博文主要讲解Hiberna ...
随机推荐
- 将HG版本库推送到Git服务器
如何将HG版本库推送到Git服务器? 目的 习惯使用HG来进行版本管理,但是GitHub代码统计比Bitbucket要丰富,所以准备主力仓库选用Bitbucket,GitHub作为备用仓库. GitH ...
- Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本
Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本 1. 框架选型的要求1 1.1. 文档多1 1.2. 跨平台1 2. html解析器特性:1 2.1. j ...
- [svc]rsyslog及logrotate小结
[root@node1 logrotate.d]# ls dracut haproxy httpd mcelog nginx ppp psacct syslog yum yum install ngi ...
- linux下启动、添加或删除服务命令
在Linux系统下,一个Services的启动.停止以及重启通常是通过/etc/init.d目录下的脚本来控制的.然而,在启动或改变运行级别时,是在/etc/rcX.d中来搜索脚本.其中X是运行级别的 ...
- 免安装Oracleclient和PL/SQL
写在前面: Oracle是典型的C/S结构,服务端提供oracle服务的实例,主要用于数据库的管理,对象的管理与存储.数据的 存储.查询.数据库资源的监控.监听等一些服务. 而client仅仅是一个与 ...
- SIGBUS 和 SIGSEGV
一.导致SIGSEGV 1.试图对仅仅读映射区域进行写操作 . 2.訪问的内存已经被释放,也就是已经不存在或者越界. 3.官方说法是: SIGSEGV --- Segment Fault. ...
- C语言函数sscanf()的用法(转)
转自:http://www.cnblogs.com/lyq105/archive/2009/11/28/1612677.html C语言函数sscanf()的用法 sscanf() - 从一个字符串中 ...
- <!--#include file= menu.shtml --> 引用出现空白
打开footer 然后 在DW里 点--->修改--->页面属性---->标题/编码----->把包括unicode签名(bom)的勾取消 就OK了 作用:可使用 .shtml ...
- Dump 分析法
云更新目前能够收集32位客户机系统(XP和win7 32位)产生的蓝屏DMP文件到服务端DUMP文件夹,我们可以通过分析蓝屏曰志来确定到底是什么导致了客户机蓝屏. 一.WinDbg是什么?它能做什么? ...
- EasyUI获取DataGrid中某一列的所有值
function count() { var rows = $('#dg'').datagrid('getRows')//获取当前页的数据行 var total = 0; for (var i = 0 ...