1
、集合过滤:
对于一个已经加载的
Customer
对象,假设对它的
orders
集合采用延迟加载机制,那么当调用
customer.getOrders().iterator()
时,
Hibernate
就会初始化
orders
集合,然后到数据库中去加载
Customer
对象所关联的
Order
对象,并且填充
orders
集合,但是很多时候我们其实只是需要关联对象中符合某些条件的一部分对象,而并不需要加载全部关联对象,而对性能带来无谓的开销。这时候我们就可以利用
Hibernate
的集合过滤功能,来处理关联对象的加载。我们看下面的代码:
List list=session.createFilter(customer.getOrders(),“where this.price>100 order by this.price”).list();
for(int i=0;i<list.size();i++){
Order order=(Order)list.get(i);
}
在上面代码中通过
session.createFilter()
方法,创建了一个集合过滤的查询对象,这个方法需要两个参数,第一个参数指定需要进行过滤操作的集合,第二个参数指定过滤集合的条件,方法返回
Query
对象。这个方法不要求它所要操作的集合对象已经初始化,但是要求包含这个集合对象的实体对象必须处于持久化状态。当执行
list()
方法时不管持久化对象的集合是否已经初始化,都会到数据库中去检索数据,为了保证在
Hibernate
缓存中不会出现
OID
相同的对象,如果集合对象已经初始化,
list()
方法不会创建新的关联实体对象,而仅仅返回已经存在的关联实体对象。如果集合对象还没有初始化,那么
list()
方法会创建关联实体对象,但是不会初始化容纳关联实体对象的集合。除了可以向集合对象添加过滤条件进行稽核过滤之外,还可以进行很多其他操作,看下面的代码:
①
、对集合对象进行分页:
List list=session.createFilter(customer.getOders(),”order by this.price asc”)
.setFirstResult(10)
.setMaxResults(50)
.list();
②、检索集合中关联对象的一个属性:
List list=session.createFilter(customer.getOrders(),”select this.ordernumber ”).list();
2
、子查询:
子查询是
SQL
语句中非常重要的功能特性,它可以在
SQL
语句中利用另外一条
SQL
语句的查询结果,在
Hibernate
中
HQL
查询同样对子查询功能提供了支持。如下面代码所示:
List list=session.createQuery(“from Customer c where 1>(select count(o) from c.orders o)”).list();
上面的程序查询订单数超过
1
的所有客户,因此和上面子查询
HQL
语句对应的
SQL
语句为:
Select * from Customer c where 1>(select count(o.id) from Order o where c.id=o.customer_ID);
如果子查询返回多条记录,则可以使用下面关键字:
all:
表示子查询语句返回的所有记录
any:
表示子查询语句返回的任意一条结果
some:
与
”any”
等价
in:
与
”=any”
等价
exists:
表示子查询语句至少返回一条记录
例如:查询存在一条订单价格大于
100
的客户
From Customer c where 100>any(select o.price from c.orders o);
如果在子查询中操作集合,
HQL
提供了一组操纵集合的函数和属性:
size()
函数和
size
属性:获得集合中元素的数量
minIndex()
函数和
minIndex
属性:对于建立了索引的集合获得最小索引值(关于集合索引参考第一部分映射值类型集合)
minElement()
函数和
minElement
属性:对于包含基本类型的元素集合,获得集合中值最小的元素
maxElement()
函数和
maxElement
属性:对于包含基本类型元素的集合,获得集合中值最大的元素
element()
函数:获得集合中所有元素
例如:查询订单数大于
0
的客户
From Customer c where size(c.orders)>0;
或者
From Customer c where c.orders.size>0;
以上
HQL
语句会生成类似如下的
SQL
语句:
Select * from customer c where 0>(select count(o.id) from order where o. customer_ID =c.id);
注:在
HQL
中子查询必须出现在
where
子句中,而且必须用一对圆括号括起来。为什么必须要出现在
where
字句之后呢?其实我们大家仔细想一下也就知道了,在
Hibernate
中查询的任何一个实体对象都要有据可循,这个“据”就是
Hibernate
的主配置文件,也就是说凡是出现在
HQL from
字句中的实体对象,都必须要在
Hibernate
主配置文件中有明确的配置。所以在
Hibernate
中无法支持
SQL
语句中的那种出现在
from
字句之后的那种动态视图子查询。