您的位置:首页 > 其它

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)

方法。

结束!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: