`
tanghier
  • 浏览: 1956 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

HQL语句的语法(笔记一)

阅读更多
一、HQL查询的from子句

from是最简单的语句,也是最基本的HQL语句。from关键字后紧跟持久化类的类名。

例如:

from Person  表明从Person持久化类中选出全部的实例

推荐为Person持久化类的每个实例起别名,例如:

from Person as p

p作为Person的实例的别名,因此也应该遵守Java的命名规则:第一个单词的首字母小写,后面每个单词的首字母大写。

命名别名时,as关键字是可选的,但为了增加可读性,建议保留。

from 后还可同时出现多个持久化类,此时将产生一个笛卡尔积或跨表的连接,但实际上这种用法很少使用,因为通常我们可能需要使用跨表的连接,此时可以考虑使用隐式连接或显示连接,而不是直接在from后紧跟多个表名。

二、关联和连接

       Hibernate使用关联映射来处理底层数据表之间的连接,一旦我们提供了正确的关联映射后,当程序通过Hibernate进行持久化访问时,将可利用Hibernate的关联来进行连接。

      HQL支持两种关联连接(join)的形式:隐式(implicit)与显示(explicit)。

隐式连接形式不适用join关键字,使用英文点号(.)来隐式连接来关联实体,而Hibernate底层将自动进行关联查询。如下HQL语句:

from Person p where p.myEvent.title > :title

上面的p.myEvent属性的实质是一个持久化实体,因此Hibernate底层隐式地自动进行连接查询。

显示连接则需要使用xxx join关键字,例如如下语句:

//使用显示连接

from Person p

inner join p.myEvent event

where event.happenDate < :endDate

使用显示连接时,可以为相关联的实体,甚至是关联集合中的全部元素指定一个别名。

Hibernate支持的HQL连接类型,可使用如下几种连接方式:

inner join(内连接),可简写成join。

left outer join(左外连接),可简写成left join。

right outer join(右外连接),可简写成right join。

full join(全连接),并不常用。

使用显示连接时,还可通过HQL的with关键字来提供额外的连接条件,例如如下HQL语句:

from Person p

inner join p.myEvent event

with p.id > event.id

where event.happenDate < :endDate

       HQL语句中的with关键字的作用基本等同于SQL99中on关键字的作用:都是用于指定连接条件。通过在HQL语句中使用with关键字,可以让HQL语句执行非等值连接查询。

      由于表连接的方式都是基于底层SQL来实现的,如果底层不支持这些外连接,那么执行对应的HQL时就会相应地引发异常。

三、隐式连接和显示连接有如下两点区别:

(1)隐式连接底层转换成SQL92的内连接,显示连接层将转换成SQL99的多表连接。

(2)隐式连接和显示连接查询后返回的结果不同。

当HQL语句中省略select关键字时,使用隐式连接查询返回的结果是多个被查询实体组成的集合。

当HQL语句中省略select关键字时,使用显示连接查询返回的结果也是集合,但集合元素是被查询持久化对象、所有被关联的持久化对象所组成的数组。

注意:

       对于Hibernate3.2.3以后的版本,如果关联实体是单个实体或单个的组件属性,HQL依然可以似乎用英文点号(.)来隐式连接关联实体或组件;但如果关联实体是集合(包括1-N关联、N-N关联和集合元素时组件等),则必须使用xxx join来显示连接关联实体或组件。

       对于集合属性的,Hibernate默认采用延迟加载策略,解决办法:

       (2.1)可以在Hibernate映射文件中指定lazy="false"来关闭延迟加载。

       (2.2)使用join fetch,通常无须指定别名,因为相关联的对象不应当在where子句(或其他任何子句)中使用。而且被关联的对象也不会再被查询的结果中直接返回,而是应该通过其父对象来访问。

使用fetch关键字时,有如下几个注意点:

       fetch不应该与setMaxResults()或setFirstResult()共用。因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,即无法预先知道精确的行数。

       fetch不能与独立的with条件一起使用。

       如果在一次查询中fetch多个集合,可以查询返回笛卡尔积,因此请多加注意。

       对bag映射而言,同时join fetch多个集合时可能出现非预期结果,因此需要谨慎使用。

      full join fetch 与right join fetch是没有任何意义的。

程序里希望预加载那些原本应延迟加载的属性,则可以通过fetch all properties来强制Hibernate立即抓取这些属性。例如:

from Document fetch all properties order by name
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics