Hibernate 高级查询技巧——集合过滤与子查询

 
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 字句之后的那种动态视图子查询。
 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值