11.子查询

对于支持子查询的数据库,Hibernate支持在查询中使用子查询。一个子查询必须被圆括号包围起来(经常是SQL聚集函数的圆括号)。甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的。

from Cat as fatcat where fatcat.weight > ( select avg(cat.weight) from DomesticCat cat )
from DomesticCat as cat where cat.name = some ( select name.nickName from Name as name )
from Cat as cat where not exists ( from Cat as mate where mate.mate = cat )
from DomesticCat as cat where cat.name not in ( select name.nickName from Name as name )

在select列表中包含一个表达式以上的子查询,你可以使用一个元组构造符(tuple constructors):

from Cat as cat where not ( cat.name, cat.color ) in ( select cat.name, cat.color from DomesticCat cat )

注意在某些数据库中(不包括Oracle与HSQL),你也可以在其他语境中使用元组构造符, 比如查询用户类型的组件与组合:

from Person where name = ('Gavin', 'A', 'King')

该查询等价于更复杂的:

from Person where name.first = 'Gavin' and name.initial = 'A' and name.last = 'King')

有两个很好的理由使你不应当作这样的事情:首先,它不完全适用于各个数据库平台;其次,查询现在依赖于映射文件中属性的顺序。

12.HQL示例

Hibernate查询可以非常的强大与复杂。实际上,Hibernate的一个主要卖点就是查询语句的威力。这里有一些例子,它们与我在最近的一个项目中使用的查询非常相似。注意你能用到的大多数查询比这些要简单的多!

下面的查询对于某个特定的客户的所有未支付的账单,在给定给最小总价值的情况下,返回订单的id,条目的数量和总价值,返回值按照总价值的结果进行排序。为了决定价格,查询使用了当前目录。作为转换结果的SQL查询,使用了ORDERORDER_LINEPRODUCTCATALOG 和PRICE 库表。

select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog.effectiveDate < sysdate and catalog.effectiveDate >= all ( select cat.effectiveDate from Catalog as cat where cat.effectiveDate < sysdate ) group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc

这简直是一个怪物!实际上,在现实生活中,我并不热衷于子查询,所以我的查询语句看起来更像这个:

select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog = :currentCatalog group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc

下面一个查询计算每一种状态下的支付的数目,除去所有处于AWAITING_APPROVAL状态的支付,因为在该状态下当前的用户作出了状态的最新改变。该查询被转换成含有两个内连接以及一个相关联的子选择的SQL查询,该查询使用了表 PAYMENTPAYMENT_STATUS 以及 PAYMENT_STATUS_CHANGE

select count(payment), status.name from Payment as payment join payment.currentStatus as status join payment.statusChanges as statusChange where payment.status.name <> PaymentStatus.AWAITING_APPROVAL or ( statusChange.timeStamp = ( select max(change.timeStamp) from PaymentStatusChange change where change.payment = payment ) and statusChange.user <> :currentUser ) group by status.name, status.sortOrder order by status.sortOrder

如果我把statusChanges实例集映射为一个列表(list)而不是一个集合(set), 书写查询语句将更加简单.

select count(payment), status.name from Payment as payment join payment.currentStatus as status where payment.status.name <> PaymentStatus.AWAITING_APPROVAL or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser group by status.name, status.sortOrder order by status.sortOrder

下面一个查询使用了MS SQL Server的 isNull()函数用以返回当前用户所属组织的组织帐号及组织未支付的账。它被转换成一个对表ACCOUNTPAYMENTPAYMENT_STATUSACCOUNT_TYPEORGANIZATION以及 ORG_USER进行的三个内连接,一个外连接和一个子选择的SQL查询。

select account, payment from Account as account left outer join account.payments as payment where :currentUser in elements(account.holder.users) and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate

对于一些数据库,我们需要弃用(相关的)子选择。

select account, payment from Account as account join account.holder.users as user left outer join account.payments as payment where :currentUser = user and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate

13.批量的UPDATE & DELETE语句

HQL现在支持UPDATE与DELETE语句.

14.小技巧 & 小窍门

你可以统计查询结果的数目而不必实际的返回他们:

( (Integer) session.iterate("select count(*) from ....").next() ).intValue()

若想根据一个集合的大小来进行排序,可以使用如下的语句:

select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name order by count(msg)

如果你的数据库支持子选择,你可以在你的查询的where子句中为选择的大小(selection size)指定一个条件:

from User usr where size(usr.messages) >= 1

如果你的数据库不支持子选择语句,使用下面的查询:

select usr.id, usr.name from User usr.name join usr.messages msg group by usr.id, usr.name having count(msg) >= 1

因为内连接(inner join)的原因,这个解决方案不能返回含有零个信息的User 类的实例, 所以这种情况下使用下面的格式将是有帮助的:

select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name having count(msg) = 0

JavaBean的属性可以被绑定到一个命名查询(named query)的参数上:

Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size"); q.setProperties(fooBean); // fooBean包含方法getName()与getSize() List foos = q.list();

通过将接口Query与一个过滤器(filter)一起使用,集合(Collections)是可以分页的:

Query q = s.createFilter( collection, "" ); // 一个简单的过滤器 q.setMaxResults(PAGE_SIZE); q.setFirstResult(PAGE_SIZE * pageNumber); List page = q.list();

通过使用查询过滤器(query filter)可以将集合(Collection)的原素分组或排序:

Collection orderedCollection = s.filter( collection, "order by this.amount" ); Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );

不用通过初始化,你就可以知道一个集合(Collection)的大小:

( (Integer) session.iterate("select count(*) from ....").next() ).intValue();

Hibernate HQL 语法大全(下)相关推荐

  1. Hibernate HQL 语法大全(上)

    Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL.但是不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承.多态 和关联之类的概念. ...

  2. Hibernate 持久化状态、HQL语句大全(转)

    Hibernate 持久化状态 在Hibernate中,最核心的概念就是对PO的状态管理.一个PO有三种状态: 1.未被持久化的VO 此时就是一个内存对象VO,由JVM管理生命周期 2.已被持久化的P ...

  3. Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询

    目录 一.Hibernate 的 HQL 查询 1.1.查询所有数据 1.2.条件查询 1.3.排序查询 1.4.统计查询 1.5.分页查询 1.6.投影查询 二.Hibernate 的 QBC 查询 ...

  4. hibernate 报错大全

    日志    使用JDK的自定义Comparator对Cllections进行排序 oracle数据库拼音排序及NLS_SORT配置 Hibernate常见错误合集 2012-05-23 19:04:0 ...

  5. hql 语法与详细解释

    hql 语法与详细解释 2010-08-26 11:50:11 标签: hql  语法  解释  休闲  职场 HQL查询 HQL查询: Criteria查询对查询条件进行了面向对象封装,符合编程人员 ...

  6. HQL语法与详细解释[整理]

     Hibernate查询语言为HQL(Hibernate Query Language),可以直接使用实体类名及属性.HQL语法类似于SQL,有SQL的关键词如select.from.order ...

  7. Hibernate——HQL语句

    HQL(Hibernate Query Language) – 官方推荐 前面的入门示例中,我们通过session.load(Employee.class, 1),也就是通过load()方法或者get ...

  8. Hibernate hql 查询指定字段并获取结果集

    Hibernate hql 查询指定字段并获取结果集 在hibernate中,用hql语句查询实体类,采用list方法的返回结果为一个List,该List中封装的对象分为以下三种情况: 1.查询全部字 ...

  9. weblogic10异常:org.hibernate.hql.ast.HqlToken

    今天部署应用到WLS10上,在运行过程中出现 ClassNotFoundException: org.hibernate.hql.ast.HqlToken 错误weblogic异常退出. GOOGLE ...

最新文章

  1. python和php-PHP和Python如何选择?或许可以考虑这三个问题
  2. SharePoint 2010 change home page或者default page
  3. QT的Q3DBars类的使用
  4. tomcat日志格式中的含义
  5. mysql触发器不起作用 navicat的bug?
  6. 科普 | 单精度、双精度、多精度和混合精度计算的区别是什么?
  7. 用.Net开发Windows服务初探
  8. qzone.class.php,[宜配屋]听图阁
  9. POJ3250(单调栈)
  10. Unity cg vertex and fragment shaders(二)
  11. 实现option上下移动_ES6原生实战Uploader工具类(从设计到实现)
  12. pytest学习(2)
  13. Matlab 2016a 安装教程【转】
  14. JVM性能优化之JVM调优
  15. Linux脚本的创建
  16. 我的 Serverless 实战 — Serverless 腾讯云文字识别(OCR)详细部署过程
  17. Python学习第2天:入门必备(基础篇)
  18. 【Linux】Linux中755权限是什么意思
  19. 用IE浏览器打开网址https显示不能访问怎么办
  20. 6、编写应用程序,计算两个非零正整数的最大公约数和最小公倍数,要求两个非零正整数从键盘输入。

热门文章

  1. 【nginx】配置nginx.conf 配置多个代理
  2. 如何编写功能测试报告?详细测试方案模板参考
  3. 使用三目运算求三个数的最大值、最小值和中间值
  4. “开放赋能”, 趣拿由“零售商”升级为“零售服务商”
  5. 在Windows中添加右键菜单选项及快捷键(转)
  6. Mac电脑安装其他系统
  7. PCL滤波工具之StatisticalOutlierRemoval深度分析
  8. Radon定理与证明
  9. 如何寻找软件外包公司?
  10. 洛谷 P1948 / loj 10074 / 一本通 1496【分层图】