Hibernate的检索方式(五)
2010-06-12 13:46
441 查看
Hibernate的检索方式(五) - [Hibernate
]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://aumy2008.blogbus.com/logs/14096736.html
五、高级查询技巧
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学习之路(十一):hibernate的检索方式(Oracle数据库)
- Hibernate的检索方式(2)hql
- [原创]java WEB学习笔记90:Hibernate学习之路-- -HQL检索方式,分页查询,命名查询语句,投影查询,报表查询
- Hibernate检索方式
- JAVAWEB开发之Hibernate详解(三)——Hibernate的检索方式、抓取策略以及利用二级缓存进行优化、解决数据库事务并发问题
- Hibernate —— HQL、QBC检索方式
- hibernate提供的5种检索数据方式
- Java程序员从笨鸟到菜鸟之(六十三)细谈Hibernate(十四)Hibernate三种检索方式详解
- hibernate检索方式——get和load检索方式的区别
- Hibernate检索方式
- Hibernate检索方式的学习2015-11-14
- Hibernate的检索方式
- Hibernate的QBC检索方式
- Hibernate的五种数据检索方式
- Hibernate基础学习(七)—检索方式
- Hibernate的检索方式详解(一)
- Hibernate的其他几种检索方式:
- 【知识整理】Hibernate的HQL检索方式使用入门
- Hibernate 检索方式
- Hibernate 检索方式