📄 queryhql.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 14 章 HQL: Hibernate查询语言</title><link rel="stylesheet" href="../shared/css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="up" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="previous" href="batch.html" title="第 13 章 批量处理(Batch processing)"><link rel="next" href="querycriteria.html" title="第 15 章 
 条件查询(Criteria Queries)
 "></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">第 14 章 HQL: Hibernate查询语言</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="batch.html">上一页</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="querycriteria.html">下一页</a></td></tr></table><hr></div><div class="chapter" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title"><a name="queryhql"></a>第 14 章 HQL: Hibernate查询语言</h2></div></div><div></div></div><p> Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构 上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态 和关联之类的概念。 </p><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-casesensitivity"></a>14.1. 大小写敏感性问题</h2></div></div><div></div></div><p> 除了Java类与属性的名称外,查询语句对大小写并不敏感。 所以 <tt class="literal">SeLeCT</tt> 与 <tt class="literal">sELEct</tt> 以及 <tt class="literal">SELECT</tt> 是相同的,但是 <tt class="literal">org.hibernate.eg.FOO</tt> 并不等价于 <tt class="literal">org.hibernate.eg.Foo</tt> 并且 <tt class="literal">foo.barSet</tt> 也不等价于 <tt class="literal">foo.BARSET</tt>。 </p><p> 本手册中的HQL关键字将使用小写字母. 很多用户发现使用完全大写的关键字会使查询语句 的可读性更强, 但我们发现,当把查询语句嵌入到Java语句中的时候使用大写关键字比较难看。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-from"></a>14.2. from子句</h2></div></div><div></div></div><p> Hibernate中最简单的查询语句的形式如下: </p><pre class="programlisting">from eg.Cat</pre><p> 该子句简单的返回<tt class="literal">eg.Cat</tt>类的所有实例。 通常我们不需要使用类的全限定名, 因为 <tt class="literal">auto-import</tt>(自动引入) 是缺省的情况。 所以我们几乎只使用如下的简单写法: </p><pre class="programlisting">from Cat</pre><p> 大多数情况下, 你需要指定一个<span class="emphasis"><em>别名</em></span>, 原因是你可能需要 在查询语句的其它部分引用到<tt class="literal">Cat</tt> </p><pre class="programlisting">from Cat as cat</pre><p> 这个语句把别名<tt class="literal">cat</tt>指定给类<tt class="literal">Cat</tt> 的实例, 这样我们就可以在随后的查询中使用此别名了。 关键字<tt class="literal">as</tt> 是可选的,我们也可以这样写: </p><pre class="programlisting">from Cat cat</pre><p> 子句中可以同时出现多个类, 其查询结果是产生一个笛卡儿积或产生跨表的连接。 </p><pre class="programlisting">from Formula, Parameter</pre><pre class="programlisting">from Formula as form, Parameter as param</pre><p> 查询语句中别名的开头部分小写被认为是实践中的好习惯, 这样做与Java变量的命名标准保持了一致 (比如,<tt class="literal">domesticCat</tt>)。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-joins"></a>14.3. 关联(Association)与连接(Join)</h2></div></div><div></div></div><p> 我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名, 这时要使用关键字<tt class="literal">join</tt>。 </p><pre class="programlisting">from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten</pre><pre class="programlisting">from Cat as cat left join cat.mate.kittens as kittens</pre><pre class="programlisting">from Formula form full join form.parameter param</pre><p> 受支持的连接类型是从ANSI SQL中借鉴来的。 </p><div class="itemizedlist"><ul type="disc" compact><li><p> <tt class="literal">inner join</tt>(内连接) </p></li><li><p> <tt class="literal">left outer join</tt>(左外连接) </p></li><li><p> <tt class="literal">right outer join</tt>(右外连接) </p></li><li><p> <tt class="literal">full join</tt> (全连接,并不常用) </p></li></ul></div><p> 语句<tt class="literal">inner join</tt>, <tt class="literal">left outer join</tt> 以及 <tt class="literal">right outer join</tt> 可以简写。 </p><pre class="programlisting">from Cat as cat join cat.mate as mate left join cat.kittens as kitten</pre><p> 通过HQL的<tt class="literal">with</tt>关键字,你可以提供额外的join条件。 </p><pre class="programlisting">from Cat as cat left join cat.kittens as kitten with kitten.bodyWeight > 10.0</pre><p> 还有,一个"fetch"连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化,这种方法在使用到集合的情况下尤其有用,对于关联和集合来说,它有效的代替了映射文件中的外联接 与延迟声明(lazy declarations). 查看 <a href="performance.html#performance-fetching" title="19.1. 
 抓取策略(Fetching strategies)
 ">第 19.1 节 “ 抓取策略(Fetching strategies) ”</a> 以获得等多的信息。 </p><pre class="programlisting">from Cat as cat inner join fetch cat.mate left join fetch cat.kittens</pre><p> 一个fetch连接通常不需要被指定别名, 因为相关联的对象不应当被用在 <tt class="literal">where</tt> 子句 (或其它任何子句)中。同时,相关联的对象 并不在查询的结果中直接返回,但可以通过他们的父对象来访问到他们。 </p><pre class="programlisting">from Cat as cat inner join fetch cat.mate left join fetch cat.kittens child left join fetch child.kittens</pre><p> 假若使用<tt class="literal">iterate()</tt>来调用查询,请注意<tt class="literal">fetch</tt>构造是不能使用的(<tt class="literal">scroll()</tt> 可以使用)。<tt class="literal">fetch</tt>也不应该与<tt class="literal">setMaxResults()</tt> 或<tt class="literal">setFirstResult()</tt>共用,这是因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数。<tt class="literal">fetch</tt>还不能与独立的 <tt class="literal">with</tt>条件一起使用。通过在一次查询中fetch多个集合,可以制造出笛卡尔积,因此请多加注意。对bag映射来说,同时join fetch多个集合角色可能在某些情况下给出并非预期的结果,也请小心。最后注意,使用<tt class="literal">full join fetch</tt> 与 <tt class="literal">right join fetch</tt>是没有意义的。 </p><p> 如果你使用属性级别的延迟获取(lazy fetching)(这是通过重新编写字节码实现的),可以使用 <tt class="literal">fetch all properties</tt> 来强制Hibernate立即取得那些原本需要延迟加载的属性(在第一个查询中)。 </p><pre class="programlisting">from Document fetch all properties order by name</pre><pre class="programlisting">from Document doc fetch all properties where lower(doc.name) like '%cats%'</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-joins-forms"></a>14.4. join 语法的形式</h2></div></div><div></div></div><p> HQL支持两种关联join的形式:<tt class="literal">implicit(隐式)</tt> 与<tt class="literal">explicit(显式)</tt>。 </p><p> 上一节中给出的查询都是使用<tt class="literal">explicit(显式)</tt>形式的,其中form子句中明确给出了join关键字。这是建议使用的方式。 </p><p> <tt class="literal">implicit(隐式)</tt>形式不使用join关键字。关联使用"点号"来进行“引用”。<tt class="literal">implicit</tt> join可以在任何HQL子句中出现.<tt class="literal">implicit</tt> join在最终的SQL语句中以inner join的方式出现。 </p><pre class="programlisting">from Cat as cat where cat.mate.name like '%s%'</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-select"></a>14.5. select子句</h2></div></div><div></div></div><p> <tt class="literal">select</tt> 子句选择将哪些对象与属性返 回到查询结果集中. 考虑如下情况: </p><pre class="programlisting">select mate from Cat as cat inner join cat.mate as mate</pre><p> 该语句将选择<tt class="literal">mate</tt>s of other <tt class="literal">Cat</tt>s。(其他猫的配偶) 实际上, 你可以更简洁的用以下的查询语句表达相同的含义: </p><pre class="programlisting">select cat.mate from Cat cat</pre><p> 查询语句可以返回值为任何类型的属性,包括返回类型为某种组件(Component)的属性: </p><pre class="programlisting">select cat.name from DomesticCat catwhere cat.name like 'fri%'</pre><pre class="programlisting">select cust.name.firstName from Customer as cust</pre><p> 查询语句可以返回多个对象和(或)属性,存放在 <tt class="literal">Object[]</tt>队列中, </p><pre class="programlisting">select mother, offspr, mate.name from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr</pre><p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -