📄 queryhql.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 15 章 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="第 14 章 批量处理(Batch processing)"><link rel="next" href="querycriteria.html" title="第 16 章 
 条件查询(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">第 15 章 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>第 15 章 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>15.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>15.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>15.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> 还有,一个"fetch"连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化,这种方法在使用到集合的情况下尤其有用,对于关联和集合来说,它有效的代替了映射文件中的外联接 与延迟声明(lazy declarations). 查看 <a href="performance.html#performance-fetching" title="20.1. 
 
 抓取策略(Fetching strategies)
 ">第 20.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><p> 注意<tt class="literal">fetch</tt>构造变量在使用了<tt class="literal">scroll()</tt> 或 <tt class="literal">iterate()</tt>函数 的查询中是不能使用的。最后注意,使用<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-select"></a>15.4. 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> 或存放在一个<tt class="literal">List</tt>对象中, </p><pre class="programlisting">select new list(mother, offspr, mate.name)from 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 DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr</pre><p> 假设类<tt class="literal">Family</tt>有一个合适的构造函数. </p><p> 你可以使用关键字<tt class="literal">as</tt>给“被选择了的表达式”指派别名: </p><pre class="programlisting">select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as nfrom Cat cat</pre><p> 这种做法在与子句<tt class="literal">select new map</tt>一起使用时最有用: </p><pre class="programlisting">select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )from Cat cat</pre><p> 该查询返回了一个<tt class="literal">Map</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>15.5. 聚集函数</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 Cat 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> 你可以在选择子句中使用数学操作符、连接以及经过验证的SQL函数:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -