6.4.3:HQL的关联和连接
2013-07-13 18:27
190 查看
当程序需要从多个数据表中取得数据时,SQL语句将会考虑使用多表连接查询。Hibernate使用关联映射来处理底层数据表之间的连接,一旦我们提供了正确的关联映射后,当程序通过Hibernate进行持久化访问时,将可利用Hibernate的关联来进行连接。
HQL支持两种关联连接形式: 隐式与显式。
隐式连接:
隐式连接形式不使用join关键字,使用英文点号(.)来隐式连接关联实体,而Hibernate底层将自动进行关联查询。例如以下HQL语句:
显式连接:
显式连接则需要使用xxx join关键字,例如以下HQL语句:
Hibernate支持的HQL连接类型直接借鉴了SQL99多表查询的关键字,可用如下几种连接方式:
HQL的连接类型
使用显式连接时,还可通过HQL的关键字with来提供额外的连接条件,例如:
还有一点必须指出:由于此处的inner join,left join,right join和full join的实质依然是基于底层SQL的内、左、右、外连接的,所以如果底层SQL不支持这些外连接,那么执行对应的HQL时就会引发异常。
对于隐式连接和显式连接还有如下两点区别:
① 隐式连接底层将转换成SQL99的交叉连接,显式连接底层将转换成SQL99的inner join、left join、right join等连接。
② 隐式连接和显式连接查询后返回的结果不同。
当HQL语句中省略select关键字时,使用隐式连接查询返回的结果是多个被查询实体组成的集合。当使用显式连接查询的HQL语句中省略select关键字时,返回的结果也是集合,但集合元素是被查询持久化对象、所有被关联的持久化对象所组成的数组。
关于隐式连接和显式连接还有非常重要的一点需要指出,这是由Hibernate版本升级所引发的问题。在Hibernate3.2.2以前的版本,Hibernate会对所有关联实体自动使用隐式连接。对于如下HQL语句:from Person p where p.myEvents.title=:eventTitle无论如何,Hibernate将对上面的p.myEvents.title自动使用隐式连接,因此上面的HQL语句总是有效的。
从Hibernate3.2.3以后,Hibernate改变了这种隐式连接的策略,还是对于这条同样的HQL语句,则可能出现以下两种情况:
① 如果myEvents是普通组件属性,或单个的关联实体,则Hibernate会自动生成隐式内连接,上面的HQL语句依然有效。
② 如果myEvents是一个集合(包括1-N,N-N关联),那么系统将会出现QueryException异常,异常提示信息为:illegal attempt to dereference collection。
根据Hibernate的官方说法,这样可以使得隐式连接更具确定性。
为此Hibernate推荐将上面的HQL语句写成:
HQL支持两种关联连接形式: 隐式与显式。
隐式连接:
隐式连接形式不使用join关键字,使用英文点号(.)来隐式连接关联实体,而Hibernate底层将自动进行关联查询。例如以下HQL语句:
from Person p where p.myEvent.title>:title上面的p.myEvent属性的实质是一个持久化实体,因此Hibernate底层隐式地自动进行连接查询。
显式连接:
显式连接则需要使用xxx join关键字,例如以下HQL语句:
from Person p inner join p.myEvent event where event.happenDate<:endDate使用显式连接时可以为相关联的实体,甚至是关联集合中的全部元素指定一个别名。
Hibernate支持的HQL连接类型直接借鉴了SQL99多表查询的关键字,可用如下几种连接方式:
inner join | 内连接,可简写为join |
left outer join | 左外连接,可简写为left join |
right outer join | 右外连接,可简写为right join |
full join | 全连接,并不常用 |
from Person p inner join p.myEvent event with p.id>event.id where event.happenDate<:endDateHibernate会将这种显式连接转换成SQL99多表连接的语法,所以HQL语句中的with关键字的作用基本等同于SQL99中的on关键字的作用:都用于指定连接条件。通过在HQL语句中使用with关键字,可以让HQL语句执行非等值连接查询。
还有一点必须指出:由于此处的inner join,left join,right join和full join的实质依然是基于底层SQL的内、左、右、外连接的,所以如果底层SQL不支持这些外连接,那么执行对应的HQL时就会引发异常。
对于隐式连接和显式连接还有如下两点区别:
① 隐式连接底层将转换成SQL99的交叉连接,显式连接底层将转换成SQL99的inner join、left join、right join等连接。
② 隐式连接和显式连接查询后返回的结果不同。
当HQL语句中省略select关键字时,使用隐式连接查询返回的结果是多个被查询实体组成的集合。当使用显式连接查询的HQL语句中省略select关键字时,返回的结果也是集合,但集合元素是被查询持久化对象、所有被关联的持久化对象所组成的数组。
关于隐式连接和显式连接还有非常重要的一点需要指出,这是由Hibernate版本升级所引发的问题。在Hibernate3.2.2以前的版本,Hibernate会对所有关联实体自动使用隐式连接。对于如下HQL语句:from Person p where p.myEvents.title=:eventTitle无论如何,Hibernate将对上面的p.myEvents.title自动使用隐式连接,因此上面的HQL语句总是有效的。
从Hibernate3.2.3以后,Hibernate改变了这种隐式连接的策略,还是对于这条同样的HQL语句,则可能出现以下两种情况:
① 如果myEvents是普通组件属性,或单个的关联实体,则Hibernate会自动生成隐式内连接,上面的HQL语句依然有效。
② 如果myEvents是一个集合(包括1-N,N-N关联),那么系统将会出现QueryException异常,异常提示信息为:illegal attempt to dereference collection。
根据Hibernate的官方说法,这样可以使得隐式连接更具确定性。
为此Hibernate推荐将上面的HQL语句写成:
from Person p inner join p.myEvents e where e.title=:eventTitle这条HQL语句将会返回一个集合,集合元素是Person实体和MyEvent实体组成的数组。
相关文章推荐
- 使用hql查询---6.4.3: 关联和连接
- Hibernate5-一对多双向关联-迫切左外连接-HQL
- NHibernate实践总结(三)HQL的theta-style join对无关联实体的连接与应用
- NHibernate实践总结(三)HQL的theta-style join对无关联实体的连接与应用
- [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解
- Hql 左连接 (left join 非表关联)
- Hibernate5-一对多双向关联-左外连接-HQL
- hql关联和连接查询实例
- 用户 '**' 登录失败。该用户与可信 SQL Server 连接无关联。
- hibernate-HQL连接查询
- Netstat –b 关联端口连接信息
- HQL左外连接及排序
- Hibernate03(无连接表的单项1-N关联)
- '用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联,做JSP项目连接数据库
- HQL连接查询【重要】
- 用户登录失败,该用户与可信SQL Server连接无关联,错误:18452
- sqlserver2005 【用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联】解决方案
- 用户sa登录失败,该用户与可信sql server连接无关联 问题处理方法
- Sql Server 2005 用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联
- Yii 三表关联 角色表、角色权限连接表、权限表