五、高级查询技巧
2、集合过滤
延迟检索策略――customer.getOrders().iterator() (加载关联对象集合),这种方式的不足:
l 全部加载
l 不能排序
2种办法可以解决上边不足,一种是通过HQL或QBC查询orders集合,还有一种办法就是使用集合过滤。
集合过滤示例:
List result=session.createFilter(customer.getOrders(), "where this.price>200 order by this.price").list(); Iterator it=result.iterator(); while(it.hasNext()){ Order order =(Order)it.next(); .....
}
Session的createFilter()方法用来过滤集合,它具有以下特定。
l 返回Qurey类型的实例。
l 第一个参数:指定一个持久化对象的集合,这个集合是否已经被初始化并没有关系,但它所属的对象必须处于持久化状态。否则抛出异常。
l 第二个参数:指定过滤条件,它由合法的HQL查询语句组成。
l 不管持久化对象的集合是否已经初始化,Query的list()方法都会执行SQL查询语句,到数据库中检索Order对象。
l 如果对象的集合已经被初始化,为了保证Session的缓存中不会出现OID相同的Order对象,Query的list()方法不会再创建Order对象,仅仅返回已经存在的Order对象的引用。
l 如果没有初始化,Query的list()方法创建相应的对象,但不会初始化所给对象的集合。(仅仅取出符合条件的对象集合,是对象集合的子集)
集合过滤的几个应用:
A、为集合排序或设置约束条件
B、 集合分页
C、 检索集合中对象的某个属性
D、检索数据库中与Customer对象的orders集合中的Order对象的属性(一个或多个)相同的所有Order对象
E、 检索Order对象的lineItems集合中LineItem对象的Item
代码示例:
List result=session.createFilter(customer.getOrders(), " order by this.price asc") .setFirstResult(10) .setMaxResults(5) .list(); List result=session.createFilter(customer.getOrders(), "select this.orderNumber") .list(); List result=session.createFilter(customer.getOrders(), "select other from Order other where other.price=this.price") .list(); List result=session.createFilter(order.getLineItems(), "select this.item")
.list();
3、子查询
HQL支持where子句中嵌入查询语句。
from Customer c where 1<(select count(o) from c.orders o) ――相关子查询
from Order o where o.price>(select avg(o1.price) from Order o1) 无关
关于子查询的用法说明:
(1)、子查询可以分为相关子查询和无关子查询。
(2)、依赖底层数据库对子查询的支持能力。
(3)、如果子查询语句返回多条记录,可以用一下关键字来衡量。
l all:表示子查询语句返回的所有记录。
l any:任意一条记录。
l some:与“any”等价。
l in:与“=any”等价。
l exists:至少返回一条记录。
例:订单的价格都不小于100的客户
from Customer c where 100>all (select o.price from c.orders o)
有一条订单的价格小于100的客户
from Customer c where 100>any (select o.price from c.orders o)
有一条订单的价格等于100的客户
from Customer c where 100=some (select o.price from c.orders o)
或
from Customer c where 100=any (select o.price from c.orders o)
或
from Customer c where 100 in (select o.price from c.orders o)
至少有一条订单的客户
from Customer c where exsist (from c.orders)
(4)、如果子查询语句查询的是集合,HQL提供了所写语法
Iterator it=session.createQurey( "from Customer c where :order in element(c.orders)") .setEntity("order",order) .list()
.iterator();
element(c.orders)等价于(from c.orders)
HQL提供了一族操纵集合的函数或者属性。
l size()函数或size属性:获取集合中元素的数目。
l minIndex()函数或minIndex属性:对于建立了索引的集合,获取最小的索引。
l maxIndex()函数或maxIndex属性:对于建立了索引的集合,获取最大的索引。
l minElement()函数或minElement属性:对于包含基本类型元素的集合,获得集合中取值最小的元素。
l maxElement()函数或maxElement属性:对于包含基本类型元素的集合,获得集合中取值最大的元素。
l elements()函数:获得集合中所有元素。
如:订单数目大于零的客户
from Customer c where c.orders.size>0
或者 from Customer c where size(c.orders)>0
4、本地SQL查询
Hibernate本地SQL查询提供了支持,为了把SQL查询返回的关系数据映射为对象,需要在SQL查询语句中为字段指定别名。
String sql1 = "select cs.ID as {c.id},cs.name as {c.name} " + "from CUSTOMERS cs where cs.ID=1";
Query query = session.createSQLQurey(sql1, "c", Customer.class);
或
String sql1 = "select {c.*} " + "from CUSTOMERS c where c.ID=1";
Query query = session.createSQLQurey(sql1, "c", Customer.class);
多个不同的对象情况
String sql1 = "select {c.*},{o.*} from CUSTOMERS c inner join ORDERS o" + " where c.ID=o.CUSTOMER_ID"; Query query = session.createSQLQurey(sql1, new String[] { "c", "o" },
new Class[] { Customer.class, Order.class });
在程序中嵌入本地SQL语句会增加维护程序代码的难度,如果数据库表的结构发生变化,必须修改相应的程序代码,因此更合理的方式是把SQL查询语句放到映射文件中:
<sql-query name="findCustomersAndOrders"><![CDATA[ select {c.*},{o.*} from CUSTOMERS c inner join ORDERS o where c.ID=o.CUSTOMER_ID ]]> <return alias="c" class="Customer"> <return alias="o" class="Order">
</sql-query>
六、查询性能优化
1、 降低访问数据库的频率,减少select语句的数目。实现手段包括:
l 使用迫切左外连接或迫切内连接检索策略。
l 对延迟加载或立即加载策略设置批量检索数目。
l 使用查询缓存。
2、避免多余加载程序不需要访问的数据。实现手段包括:
l 使用延迟检索策略。
l 使用集合过滤。
3、 避免报表查询数据占用缓存。实现手段为利用投影查询功能,查询出实体的部分属性。
4、减少select语句中的字段,从而降低访问数据库的数据量。实现手段为利用Query的iterate()方法。
iterate()方法:
Query接口的iterate()方法和list()方法都能执行SQL查询语句。
list()首先检索ID字段,然后根据ID字段到Hibernate第一缓存以及第二级缓存中查找匹配的对象,如果存在,就直接把它加入到查询结果集中,否则就只想额外的select语句,根据ID字段数据库中检索该对象。
查询缓存
查询缓存适应以下场合:
l 在应用程序运行时经常使用的查询语句。
l 很少对与查询语句关联的数据库数据进行插入、删除或更新操作。
查询语句启用查询缓存的步骤如下:
A、配置第二级缓存。
B、 在Hibernate的hibernate.properties配置文件中设置查询缓存属性:
hibernate.cache.use_query_cache=true
C、启用查询缓存。调用Query接口的setCacheable(true)方法。
分享到:
相关推荐
Hibernate的检索方式: 5种
介绍了HIBERNATE的检索策略,可以此作为指引进行学习
Hibernate检索方式 孙卫琴的 pdf
java-Hibernate 检索
NULL 博文链接:https://364232252.iteye.com/blog/2368725
hibernate5--4.检索方式及策略
NULL 博文链接:https://364232252.iteye.com/blog/2368583
Hibernate数据检索(HQL)笔记Hibernate数据检索(HQL)笔记Hibernate数据检索(HQL)笔记Hibernate数据检索(HQL)笔记
魔乐科技,李兴华老师的Hibernate教程笔记,对Hibernate的基础知识进行了比较详细的讲解,对初学者有一个比较笼统的介绍,是带我们入门Hibernate的不二选择。
基于Spring的Hibernate Search全文检索功能示例 实例下载
Hibernate的检索策略包括类级别检索策略和关联级别检索策略。
hibernate的注解开发 注解开发关联映射 HQL、QBC、本地SQL检索数据
本人在厦门邦初培训时候 使用的快速入门精简文档 Session缓存的作用 Session清理缓存的时间点 对象的临时状态、持久状态和游离状态 用session的update()方法使游离对象转变为持久化对象。...本地SQL检索方式
Hibernate数据检索(HQL).rar
使用hibernate search实现全文检索和文档管理功能: 1 全文检索 2 手动生成索引 3 文档上传(自动建立索引) 4 文档更新(自动建立索引) 5 文档删除 使用说明: 1 需要先恢复数据库 searchDB_2008sqlserver.bak 2 ...
总结hibernate框架的常用检索方式 1、hibernate框架的检索方式有以下几种: OID检索:根据唯一标识OID检索数据 对象导航检索:根据某个对象导航查询与该对象关联的对象数据 HQL检索:通过query接口对象查询 QBC...
本PPT描述了对SHH框架中hibernate数据检索功能的描述,用户可以更快的学习Hibernate数据检索
hibernate的延迟检索在轻量级J2EE框架中的应用
使用 hibernate-search 实现全文检索及文档管理的例子 1 全文检索 2 手动重新建立索引 3 文档上传(自动建立索引) 4 文档更新(自动建立索引) 5 文档删除