📄 queryhql.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 11 章 Hibernate查询语言(Query Language), 即HQL</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="transactions.html" title="第 10 章 事务和并行(Transactions And Concurrency)"><link rel="next" href="querycriteria.html" title="第 12 章 条件查询(Criteria Query)"></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">第 11 章 Hibernate查询语言(Query Language), 即HQL</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="transactions.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>第 11 章 Hibernate查询语言(Query Language), 即HQL</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>11.1. 大小写敏感性(Case Sensitivity)</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">net.sf.hibernate.eg.FOO</tt> 和 <tt class="literal">net.sf.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>11.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>类的实例。 </p><p> 大部分情况下,你需要赋予它一个<span class="emphasis"><em>别名(alias)</em></span>,因为你在查询的其他地方也会引用这个<tt class="literal">Cat</tt>。 </p><pre class="programlisting">from eg.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 eg.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>11.3. 联合(Associations)和连接(joins)</h2></div></div><div></div></div><p> 你可以使用<tt class="literal">join</tt>定义两个实体的连接,同时指明别名。 </p><pre class="programlisting">from eg.Cat as cat inner join cat.mate as mate left outer join cat.kittens as kittenfrom eg.Cat as cat left join cat.mate.kittens as kittensfrom 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 eg.Cat as cat join cat.mate as mate left join cat.kittens as kitten</pre><p> 并且,加上 "fetch"后缀的抓取连接可以让联合的对象随着它们的父对象的初始化而初始化,只需要一个select语句。这在初始化一个集合的时候特别有用。它有效地覆盖了映射文件中对关联和集合的外连接定义。 </p><pre class="programlisting">from eg.Cat as cat inner join fetch cat.mate left join fetch cat.kittens</pre><p> 抓取连接一般不需要赋予别名,因为被联合的对象应该不会在<tt class="literal">where</tt>子句(或者任何其它子句)中出现。并且,被联合的对象也不会在查询结果中直接出现。它们是通过父对象进行访问的。 </p><p> 请注意,目前的实现中,在一次查询中只会抓取一个集合(其他的一切都做不到。)(?原文为:only one collection role may be fetched in a query)。也请注意,在使用<tt class="literal">scroll()</tt>或者 <tt class="literal">iterate()</tt>方式调用的查询中,是禁止使用<tt class="literal">fetch</tt>构造的。最后,请注意<tt class="literal">full join fetch</tt>和<tt class="literal">right join fetch</tt>是没有意义的。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-select"></a>11.4. select子句</h2></div></div><div></div></div><p> <tt class="literal">select</tt>子句选择在结果集中返回哪些对象和属性。思考一下下面的例子: </p><pre class="programlisting">select mate from eg.Cat as cat inner join cat.mate as mate</pre><p> 这个查询会选择出作为其它猫(<tt class="literal">Cat</tt>)朋友(<tt class="literal">mate</tt>)的那些猫。当然,你可以更加直接的写成下面的形式: </p><pre class="programlisting">select cat.mate from eg.Cat cat</pre><p> 你甚至可以选择集合元素,使用特殊的<tt class="literal">elements</tt>功能。下面的查询返回所有猫的小猫。 </p><pre class="programlisting">select elements(cat.kittens) from eg.Cat cat</pre><p> 查询可以返回任何值类型的属性,包括组件类型的属性: </p><pre class="programlisting">select cat.name from eg.DomesticCat catwhere cat.name like 'fri%'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 eg.DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr</pre><p> 或者实际上是类型安全的Java对象 </p><pre class="programlisting">select new Family(mother, mate, offspr)from eg.DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr</pre><p> 上面的代码假定<tt class="literal">Family</tt>有一个合适的构造函数。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-aggregation"></a>11.5. 统计函数(Aggregate functions)</h2></div></div><div></div></div><p> HQL查询可以返回属性的统计函数的结果。 </p><pre class="programlisting">select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)from eg.Cat cat</pre><p> 在<tt class="literal">select</tt>子句中,统计函数的变量也可以是集合。 </p><pre class="programlisting">select cat, count( elements(cat.kittens) ) from eg.Cat cat group by cat</pre><p> 下面是支持的统计函数列表: </p><div class="itemizedlist"><ul type="disc" compact><li><p> <tt class="literal">avg(...), sum(...), min(...), max(...)</tt> </p></li><li><p> <tt class="literal">count(*)</tt> </p></li><li><p> <tt class="literal">count(...), count(distinct ...), count(all...)</tt> </p></li></ul></div><p> <tt class="literal">distinct</tt> 和 <tt class="literal">all</tt>关键字的用法和语义与SQL相同。 </p><pre class="programlisting">select distinct cat.name from eg.Cat catselect count(distinct cat.name), count(cat) from eg.Cat cat</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-polymorphism"></a>11.6. 多态(polymorphism)查询</h2></div></div><div></div></div><p> 类似下面的查询: </p><pre class="programlisting">from eg.Cat as cat</pre><p> 返回的实例不仅仅是<tt class="literal">Cat</tt>,也有可能是子类的实例,比如<tt class="literal">DomesticCat</tt>。Hibernate查询可以在<tt class="literal">from</tt>子句中使用<span class="emphasis"><em>任何</em></span>Java类或者接口的名字。查询可能返回所有继承自这个类或者实现这个接口的持久化类的实例。下列查询会返回所有的持久化对象: </p><pre class="programlisting">from java.lang.Object o</pre><p> 可能有多个持久化类都实现了<tt class="literal">Named</tt>接口: </p><pre class="programlisting">from eg.Named n, eg.Named m where n.name = m.name</pre><p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -