📄 queryhql.html
字号:
请注意,上面两个查询都使用了超过一个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>11.7. where子句</h2></div></div><div></div></div><p> <tt class="literal">where</tt>子句让你缩小你要返回的实例的列表范围。 </p><pre class="programlisting">from eg.Cat as cat where cat.name='Fritz'</pre><p> 返回所有名字为'Fritz'的<tt class="literal">Cat</tt>的实例。 </p><pre class="programlisting">select foo from eg.Foo foo, eg.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 eg.Cat cat where cat.mate.name is not null</pre><p> 这个查询会被翻译为带有一个表间(inner)join的SQL查询。如果你写下类似这样的语句: </p><pre class="programlisting">from eg.Foo foo where foo.bar.baz.customer.address.city is not null</pre><p> 你最终会得到的查询,其对应的SQL需要4个表间连接。 </p><p> <tt class="literal">=</tt>操作符不仅仅用于判断属性是否相等,也可以用于实例: </p><pre class="programlisting">from eg.Cat cat, eg.Cat rival where cat.mate = rival.mateselect cat, mate from eg.Cat cat, eg.Cat matewhere cat.mate = mate</pre><p> 特别的,小写的<tt class="literal">id</tt>可以用来表示一个对象的惟一标识。(你可以使用它的属性名。) </p><pre class="programlisting">from eg.Cat as cat where cat.id = 123from eg.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 = 123456from bank.Account accountwhere account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> 又一次,第二个查询不需要表间连接。 </p><p> 类似的,在存在多态持久化的情况下,特殊属性<tt class="literal">class</tt>用于获取某个实例的辨识值。在where子句中嵌入的Java类名将会转换为它的辨识值。 </p><pre class="programlisting">from eg.Cat cat where cat.class = eg.DomesticCat</pre><p> 你也可以指定组件(或者是组件的组件,依次类推)或者组合类型中的属性。但是在一个存在路径的表达式中,最后不能以一个组件类型的属性结尾。(这里不是指组件的属性)。比如,假若<tt class="literal">store.owner</tt>这个实体的的<tt class="literal">address</tt>是一个组件 </p><pre class="programlisting">store.owner.address.city //okaystore.owner.address //error!</pre><p> “任意(any)”类型也有特殊的<tt class="literal">id</tt>属性和<tt class="literal">class</tt>属性,这可以让我们用下面的形式来表达连接(这里<tt class="literal">AuditLog.item</tt>是一个对应到<tt class="literal"><ant></tt>的属性)。 </p><pre class="programlisting">from eg.AuditLog log, eg.Payment payment where log.item.class = 'eg.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>11.8. 表达式(Expressions)</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> 字符串连接 || </p></li><li><p> SQL标量( scalar)函数,例如 <tt class="literal">upper()</tt> 和 <tt class="literal">lower()</tt> </p></li><li><p> 没有前缀的 <tt class="literal">( )</tt>表示分组 </p></li><li><p> <tt class="literal">in</tt>, <tt class="literal">between</tt>, <tt class="literal">is null</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"> 比如 Color.TABBY</tt> </p></li></ul></div><p> <tt class="literal">in</tt> 和 <tt class="literal">between</tt> 可以如下例一样使用: </p><pre class="programlisting">from eg.DomesticCat cat where cat.name between 'A' and 'B'from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )</pre><p> 其否定形式为 </p><pre class="programlisting">from eg.DomesticCat cat where cat.name not between 'A' and 'B'from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )</pre><p> 类似的,<tt class="literal">is null</tt>和<tt class="literal">is not null</tt>可以用来测试null值。 </p><p> 通过在Hibernate配置中声明HQL查询的替换方式,Boolean也是很容易在表达式中使用的: </p><pre class="programlisting"><property name="hibernate.query.substitutions">true 1, false 0</property></pre><p> 在从HQL翻译成SQL的时候,关键字<tt class="literal">true</tt>和<tt class="literal">false</tt>就会被替换成<tt class="literal">1</tt>和<tt class="literal">0</tt>。 </p><pre class="programlisting">from eg.Cat cat where cat.alive = true</pre><p> 你可以用特殊属性<tt class="literal">size</tt>来测试一个集合的长度,或者用特殊的<tt class="literal">size()</tt>函数也可以。 </p><pre class="programlisting">from eg.Cat cat where cat.kittens.size > 0from eg.Cat cat where size(cat.kittens) > 0</pre><p> 对于排序集合,你可以用<tt class="literal">minIndex</tt>和<tt class="literal">maxIndex</tt>来获取其最大索引值和最小索引值。类似的,<tt class="literal">minElement</tt> 和<tt class="literal">maxElement</tt> 可以用来获取集合中最小和最大的元素,前提是必须是基本类型的集合。 </p><pre class="programlisting">from Calendar cal where cal.holidays.maxElement > current date</pre><p> 也有函数的形式(和上面的形式不同,函数形式是大小写不敏感的): </p><pre class="programlisting">from Order order where maxindex(order.items) > 100from Order order where minelement(order.items) > 10000</pre><p> SQL中的<tt class="literal">any, some, all, exists, in</tt>功能也是支持的,前提是必须把集合的元素或者索引集作为它们的参数(使用<tt class="literal">element</tt>和<tt class="literal">indices</tt>函数),或者使用子查询的结果作为参数。 </p><pre class="programlisting">select mother from eg.Cat as mother, eg.Cat as kitwhere kit in elements(foo.kittens)select p from eg.NameList list, eg.Person pwhere p.name = some elements(list.names)from eg.Cat cat where exists elements(cat.kittens)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -