📄 queryhql.html
字号:
</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>15.6. 多态查询</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>15.7. 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> 将涉及到完全不同的数据库中的列。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="queryhql-expressions"></a>15.8. 表达式</h2></div></div><div></div></div><p> 在<tt class="literal">where</tt>子句中允许使用的表达式包括 大多数你可以在SQL使用的表达式种类: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 数学运算符<tt class="literal">+, -, *, /</tt> </p></li><li><p> 二进制比较运算符<tt class="literal">=, >=, <=, <>, !=, like</tt> </p></li><li><p> 逻辑运算符<tt class="literal">and, or, not</tt> </p></li><li><p> <tt class="literal">in</tt>, <tt class="literal">not in</tt>, <tt class="literal">between</tt>, <tt class="literal">is null</tt>, <tt class="literal">is not null</tt>, <tt class="literal">is empty</tt>, <tt class="literal">is not empty</tt>, <tt class="literal">member of</tt> and <tt class="literal">not member of</tt> </p></li><li><p> "简单的" case, <tt class="literal">case ... when ... then ... else ... end</tt>,和 "搜索" case, <tt class="literal">case when ... then ... else ... end</tt> </p></li><li><p> 字符串连接符<tt class="literal">...||...</tt> or <tt class="literal">concat(...,...)</tt> </p></li><li><p> <tt class="literal">current_date()</tt>, <tt class="literal">current_time()</tt>, <tt class="literal">current_timestamp()</tt> </p></li><li><p> <tt class="literal">second(...)</tt>, <tt class="literal">minute(...)</tt>, <tt class="literal">hour(...)</tt>, <tt class="literal">day(...)</tt>, <tt class="literal">month(...)</tt>, <tt class="literal">year(...)</tt>, </p></li><li><p> EJB-QL 3.0定义的任何函数或操作:<tt class="literal">substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length()</tt> </p></li><li><p> <tt class="literal">coalesce()</tt> 和 <tt class="literal">nullif()</tt> </p></li><li><p> <tt class="literal">cast(... as ...)</tt>, 其第二个参数是某Hibernate类型的名字,以及<tt class="literal">extract(... from ...)</tt>,只要ANSI <tt class="literal">cast()</tt> 和 <tt class="literal">extract()</tt> 被底层数据库支持 </p></li><li><p> 任何数据库支持的SQL标量函数,比如<tt class="literal">sign()</tt>, <tt class="literal">trunc()</tt>, <tt class="literal">rtrim()</tt>, <tt class="literal">sin()</tt> </p></li><li><p> JDBC参数传入 <tt class="literal">?</tt> </p></li><li><p> 命名参数<tt class="literal">:name</tt>, <tt class="literal">:start_date</tt>, <tt class="literal">:x1</tt> </p></li><li><p> SQL 直接常量 <tt class="literal">'foo'</tt>, <tt class="literal">69</tt>, <tt class="literal">'1970-01-01 10:00:01.0'</tt> </p></li><li><p> Java <tt class="literal">public static final</tt> 类型的常量 <tt class="literal">eg.Color.TABBY</tt> </p></li></ul></div><p> 关键字<tt class="literal">in</tt>与<tt class="literal">between</tt>可按如下方法使用: </p><pre class="programlisting">from DomesticCat cat where cat.name between 'A' and 'B'</pre><pre class="programlisting">from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )</pre><p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -