Hibernate HQL 语法大全(下)
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查询,使用了ORDER, ORDER_LINE, PRODUCT, CATALOG 和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查询,该查询使用了表 PAYMENT, PAYMENT_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()函数用以返回当前用户所属组织的组织帐号及组织未支付的账。它被转换成一个对表ACCOUNT, PAYMENT, PAYMENT_STATUS, ACCOUNT_TYPE, ORGANIZATION以及 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语句.
你可以统计查询结果的数目而不必实际的返回他们:
( (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 语法大全(下)相关推荐
- Hibernate HQL 语法大全(上)
Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL.但是不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承.多态 和关联之类的概念. ...
- Hibernate 持久化状态、HQL语句大全(转)
Hibernate 持久化状态 在Hibernate中,最核心的概念就是对PO的状态管理.一个PO有三种状态: 1.未被持久化的VO 此时就是一个内存对象VO,由JVM管理生命周期 2.已被持久化的P ...
- Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询
目录 一.Hibernate 的 HQL 查询 1.1.查询所有数据 1.2.条件查询 1.3.排序查询 1.4.统计查询 1.5.分页查询 1.6.投影查询 二.Hibernate 的 QBC 查询 ...
- hibernate 报错大全
日志 使用JDK的自定义Comparator对Cllections进行排序 oracle数据库拼音排序及NLS_SORT配置 Hibernate常见错误合集 2012-05-23 19:04:0 ...
- hql 语法与详细解释
hql 语法与详细解释 2010-08-26 11:50:11 标签: hql 语法 解释 休闲 职场 HQL查询 HQL查询: Criteria查询对查询条件进行了面向对象封装,符合编程人员 ...
- HQL语法与详细解释[整理]
Hibernate查询语言为HQL(Hibernate Query Language),可以直接使用实体类名及属性.HQL语法类似于SQL,有SQL的关键词如select.from.order ...
- Hibernate——HQL语句
HQL(Hibernate Query Language) – 官方推荐 前面的入门示例中,我们通过session.load(Employee.class, 1),也就是通过load()方法或者get ...
- Hibernate hql 查询指定字段并获取结果集
Hibernate hql 查询指定字段并获取结果集 在hibernate中,用hql语句查询实体类,采用list方法的返回结果为一个List,该List中封装的对象分为以下三种情况: 1.查询全部字 ...
- weblogic10异常:org.hibernate.hql.ast.HqlToken
今天部署应用到WLS10上,在运行过程中出现 ClassNotFoundException: org.hibernate.hql.ast.HqlToken 错误weblogic异常退出. GOOGLE ...
最新文章
- python和php-PHP和Python如何选择?或许可以考虑这三个问题
- SharePoint 2010 change home page或者default page
- QT的Q3DBars类的使用
- tomcat日志格式中的含义
- mysql触发器不起作用 navicat的bug?
- 科普 | 单精度、双精度、多精度和混合精度计算的区别是什么?
- 用.Net开发Windows服务初探
- qzone.class.php,[宜配屋]听图阁
- POJ3250(单调栈)
- Unity cg vertex and fragment shaders(二)
- 实现option上下移动_ES6原生实战Uploader工具类(从设计到实现)
- pytest学习(2)
- Matlab 2016a 安装教程【转】
- JVM性能优化之JVM调优
- Linux脚本的创建
- 我的 Serverless 实战 — Serverless 腾讯云文字识别(OCR)详细部署过程
- Python学习第2天:入门必备(基础篇)
- 【Linux】Linux中755权限是什么意思
- 用IE浏览器打开网址https显示不能访问怎么办
- 6、编写应用程序,计算两个非零正整数的最大公约数和最小公倍数,要求两个非零正整数从键盘输入。
热门文章
- 【nginx】配置nginx.conf 配置多个代理
- 如何编写功能测试报告?详细测试方案模板参考
- 使用三目运算求三个数的最大值、最小值和中间值
- “开放赋能”, 趣拿由“零售商”升级为“零售服务商”
- 在Windows中添加右键菜单选项及快捷键(转)
- Mac电脑安装其他系统
- PCL滤波工具之StatisticalOutlierRemoval深度分析
- Radon定理与证明
- 如何寻找软件外包公司?
- 洛谷 P1948 / loj 10074 / 一本通 1496【分层图】