📄 queryhql.html
字号:
或存放在一个<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>14.6. 聚集函数</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函数: </p><pre class="programlisting">select cat.weight + sum(kitten.weight) from Cat cat join cat.kittens kittengroup by cat.id, cat.weight</pre><pre class="programlisting">select firstName||' '||initial||' '||upper(lastName) from Person</pre><p> 关键字<tt class="literal">distinct</tt>与<tt class="literal">all</tt> 也可以使用,它们具有与SQL相同的语义. </p><pre class="programlisting">select distinct cat.name from Cat catselect count(distinct cat.name), count(cat) from 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>14.7. 多态查询</h2></div></div><div></div></div><p> 一个如下的查询语句: </p><pre class="programlisting">from 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 Named n, Named m where n.name = m.name</pre><p> 注意,最后的两个查询将需要超过一个的SQL <tt class="literal">SELECT</tt>.这表明<tt class="literal">order by</tt>子句 没有对整个结果集进行正确的排序. (这也说明你不能对这样的查询使用<tt class="literal">Query.scroll()</tt>方法.) </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-where"></a>14.8. where子句</h2></div></div><div></div></div><p> <tt class="literal">where</tt>子句允许你将返回的实例列表的范围缩小. 如果没有指定别名,你可以使用属性名来直接引用属性: </p><pre class="programlisting">from Cat where name='Fritz'</pre><p> 如果指派了别名,需要使用完整的属性名: </p><pre class="programlisting">from Cat as cat where cat.name='Fritz'</pre><p> 返回名为(属性name等于)'Fritz'的<tt class="literal">Cat</tt>类的实例。 </p><pre class="programlisting">select foo from Foo foo, Bar barwhere foo.startDate = bar.date</pre><p> 将返回所有满足下面条件的<tt class="literal">Foo</tt>类的实例: 存在如下的<tt class="literal">bar</tt>的一个实例,其<tt class="literal">date</tt>属性等于 <tt class="literal">Foo</tt>的<tt class="literal">startDate</tt>属性。 复合路径表达式使得<tt class="literal">where</tt>子句非常的强大,考虑如下情况: </p><pre class="programlisting">from Cat cat where cat.mate.name is not null</pre><p> 该查询将被翻译成为一个含有表连接(内连接)的SQL查询。如果你打算写像这样的查询语句 </p><pre class="programlisting">from Foo foo where foo.bar.baz.customer.address.city is not null</pre><p> 在SQL中,你为达此目的将需要进行一个四表连接的查询。 </p><p> <tt class="literal">=</tt>运算符不仅可以被用来比较属性的值,也可以用来比较实例: </p><pre class="programlisting">from Cat cat, Cat rival where cat.mate = rival.mate</pre><pre class="programlisting">select cat, mate from Cat cat, Cat matewhere cat.mate = mate</pre><p> 特殊属性(小写)<tt class="literal">id</tt>可以用来表示一个对象的唯一的标识符。(你也可以使用该对象的属性名。) </p><pre class="programlisting">from Cat as cat where cat.id = 123from Cat as cat where cat.mate.id = 69</pre><p> 第二个查询是有效的。此时不需要进行表连接! </p><p> 同样也可以使用复合标识符。比如<tt class="literal">Person</tt>类有一个复合标识符,它由<tt class="literal">country</tt>属性 与<tt class="literal">medicareNumber</tt>属性组成。 </p><pre class="programlisting">from bank.Person personwhere person.id.country = 'AU' and person.id.medicareNumber = 123456</pre><pre class="programlisting">from bank.Account accountwhere account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> 第二个查询也不需要进行表连接。 </p><p> 同样的,特殊属性<tt class="literal">class</tt>在进行多态持久化的情况下被用来存取一个实例的鉴别值(discriminator value)。 一个嵌入到where子句中的Java类的名字将被转换为该类的鉴别值。 </p><pre class="programlisting">from Cat cat where cat.class = DomesticCat</pre><p> 你也可以声明一个属性的类型是组件或者复合用户类型(以及由组件构成的组件等等)。永远不要尝试使用以组件类型来结尾的路径表达式(path-expression) (与此相反,你应当使用组件的一个属性来结尾)。 举例来说,如果<tt class="literal">store.owner</tt>含有一个包含了组件的实体<tt class="literal">address</tt> </p><pre class="programlisting">store.owner.address.city // 正确store.owner.address // 错误!</pre><p> 一个“任意”类型有两个特殊的属性<tt class="literal">id</tt>和<tt class="literal">class</tt>, 来允许我们按照下面的方式表达一个连接(<tt class="literal">AuditLog.item</tt> 是一个属性,该属性被映射为<tt class="literal"><any></tt>)。 </p><pre class="programlisting">from AuditLog log, Payment payment where log.item.class = 'Payment' and log.item.id = payment.id</pre><p> 注意,在上面的查询与句中,<tt class="literal">log.item.class</tt> 和 <tt class="literal">payment.class</tt> 将涉及到完全不同的数据库中的列。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -