对于一个已经加载的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字句之后的那种动态视图子查询。