数据查询代码中最为关键的部分。注:博文并没有全面讲各个HQL的语法细节,只是单单讲述非常基本的脉络和一些小见解。
HQL(Hibernate Query Language)简介
HQL允许我们从面向对象的角度——类和类的属性,表达SQL中的几乎全部操作。
HibernateAPI支持通过列表、迭代和滚动执行查询
支持具体名和定位的查询绑定参数
API支持应用级别的查询提示
支持像SQL的限制、投影、联结、子查询和函数调用
如何执行查询
- 创建查询对象
- 参数绑定
利用定位或者利用具体名参数绑定。两者相比之下,前者参数绑定位置的每一个变化都会影响到参数绑定的代码,造成易破碎的弱点 - 执行查询
在XML元数据中定义具体名查询,如
基本的HQL查询
1.选择
该查询指的是,单个持久化类中的一个选择(被选的数据中的某列)
from Item
生成如下SQL
select i.ItemID, i.ItemName from Item i
作为面向对象的查询语言,HQL支持多态查询,可以相对应的查询其实体类及子类的所有实例:
from worker
该语句 返回类型 为worker的对象,是个抽象类。具体的对象为hourlyWorker及salaryWorker两个子类实例,可以通过该方法来查询所有表(适用范围)
2.限制
在查询返回的对象的属性值中表达约束,可用于select、update或者delete中
补充:SQL中,NOTNULLCOLUMN=NULL与null=null都是指取值为null的意思,而不是为true。测试一个值是否为null需要操作符IS NULL
常用比较操作符:
比较表达式
逻辑表达式
包含集合的表达式
from Item i, Category c where i.id='123' and i member of c.items
该语句返回包含主键为'123'的item实例及与其相关的所有Category的实例
补充:member of 用判断是否为成员对象
排序结果查询
所有查询语言都提供一些排序查询结果机制
多种属性进行排序
from User u order by u.lastname asc, u.firstname desc
上面HQL查询语句,会以lastname属性进行升序排序,以firstname属性进行降序排序
3.投影
允许准确指定查询结果集中哪些对象或者对象的哪些属性
实体和标量值的简单投影
from Item i, Bird b;
Iterator pairs = query.list().iterator();
while(pairs.hasNext()){
Object[] pair = (Object[])pair.next();
Item i = (Item)pair[0];
Bird b = (Bird)pair[1];
}
返回一个乘积,结果集包含了两张表的每一种可能的组合 获取唯一的结果
4.联结
举个栗子,现在有集合A(左边),集合B(右边),以及A与B的交集C
内联结:
利用内联结可以获取A与B的公共部分C
select * from A a inner join B b on a.aid = b.aid;
这条语句的结果集与下面这条语句是一样的
select * from A a, B b where a.aid = b.bid;
左外联结:
而用左外联结可以取出A(不包含公共部分, 左边)与交集C
select * from A a left outer join B b on a.aid = b.aid;
右外联结:
可以获取交集C与B(不包含公共部分,右边)
select * from A a right outer join B b on a.aid = b.bid;
动态抓取策略:
当映射文件中的lazy="false",Hibernate执行必要的SQL,保证始终加载需要的对象。意味一条HQL可能同时会产生几条SQL操作
当from字句通过fetch关键字即时抓取时,动态的抓取策略将忽略全局的抓取策略(XML映射文件的配置)
from A a left join fetch B b on a.aid =b.aid;
5.子查询(subselect)
子查询,内嵌在另一个查询中的查询,是SQL的一项重要且强大的特性。
使用限制,由于HQL是都不能传递闭包,而且返回的查询结果也可能不是表格,所以HQL只支持where的子查询,而不支持from。
相关嵌套,指子查询中是否从外部查询中,引用了对象的别名,从而使用该对象的关联对象,如:
from User u where 10 < (select count(i) from u.items i where i.saleNum is not null)
本质是,该查询语句是否与User的组合对象items联合一起查询
不相关查询,相反,该查询没有用对象的组合对象的属性值作为查询条件,即没有从外部对象中引用别名,如
from Bid bid where bid.amount + 1 >= (select max(b.amount) from Bid bid)
该语句中的子查询先返回整个系统中的最高的出价金额,外部查询然后返回金额与最高出价金额差
在一元内的所有出价
性能比较,通常地,一个简单的关联子查询的性能成本类似于一个联结成本。而不关联子插叙并没有什么害处,在方便之时没有理由不用。