当前访客身份:游客 [ 登录  | 注册加入尚学堂]
直播

我来了!

拥有积分:4024
尚学堂雄起!!威武。。。

博客分类

笔记中心

课题中心

提问中心

答题中心

解答题中心

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

我来了! 发表于 2年前 (2014-07-23 10:28:44)  |  评论(0)  |  阅读次数(603)| 0 人收藏此文章,   我要收藏   
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 字句之后的那种动态视图子查询。
分享到:0
关注微信,跟着我们扩展技术视野。每天推送IT新技术文章,每周聚焦一门新技术。微信二维码如下:
微信公众账号:尚学堂(微信号:bjsxt-java)
声明:博客文章版权属于原创作者,受法律保护。如果侵犯了您的权利,请联系管理员,我们将及时删除!
(邮箱:webmaster#sxt.cn(#换为@))
北京总部地址:北京市海淀区西三旗桥东建材城西路85号神州科技园B座三层尚学堂 咨询电话:400-009-1906 010-56233821
Copyright 2007-2015 北京尚学堂科技有限公司 京ICP备13018289号-1 京公网安备11010802015183