ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 14.8\. where子句 `where`子句允许你将返回的实例列表的范围缩小. 如果没有指定别名,你可以使用属性名来直接引用属性: ``` from Cat where name='Fritz' ``` 如果指派了别名,需要使用完整的属性名: ``` from Cat as cat where cat.name='Fritz' ``` 返回名为(属性name等于)'Fritz'的`Cat`类的实例。 ``` select foo from Foo foo, Bar bar where foo.startDate = bar.date ``` 将返回所有满足下面条件的`Foo`类的实例: 存在如下的`bar`的一个实例,其`date`属性等于 `Foo`的`startDate`属性。 复合路径表达式使得`where`子句非常的强大,考虑如下情况: ``` from Cat cat where cat.mate.name is not null ``` 该查询将被翻译成为一个含有表连接(内连接)的SQL查询。如果你打算写像这样的查询语句 ``` from Foo foo where foo.bar.baz.customer.address.city is not null ``` 在SQL中,你为达此目的将需要进行一个四表连接的查询。 `=`运算符不仅可以被用来比较属性的值,也可以用来比较实例: ``` from Cat cat, Cat rival where cat.mate = rival.mate ``` ``` select cat, mate from Cat cat, Cat mate where cat.mate = mate ``` 特殊属性(小写)`id`可以用来表示一个对象的唯一的标识符。(你也可以使用该对象的属性名。) ``` from Cat as cat where cat.id = 123 from Cat as cat where cat.mate.id = 69 ``` 第二个查询是有效的。此时不需要进行表连接! 同样也可以使用复合标识符。比如`Person`类有一个复合标识符,它由`country`属性 与`medicareNumber`属性组成。 ``` from bank.Person person where person.id.country = 'AU' and person.id.medicareNumber = 123456 ``` ``` from bank.Account account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456 ``` 第二个查询也不需要进行表连接。 同样的,特殊属性`class`在进行多态持久化的情况下被用来存取一个实例的鉴别值(discriminator value)。 一个嵌入到where子句中的Java类的名字将被转换为该类的鉴别值。 ``` from Cat cat where cat.class = DomesticCat ``` 你也可以声明一个属性的类型是组件或者复合用户类型(以及由组件构成的组件等等)。永远不要尝试使用以组件类型来结尾的路径表达式(path-expression) (与此相反,你应当使用组件的一个属性来结尾)。 举例来说,如果`store.owner`含有一个包含了组件的实体`address` ``` store.owner.address.city // 正确 store.owner.address // 错误! ``` 一个“任意”类型有两个特殊的属性`id`和`class`, 来允许我们按照下面的方式表达一个连接(`AuditLog.item` 是一个属性,该属性被映射为`<any>`)。 ``` from AuditLog log, Payment payment where log.item.class = 'Payment' and log.item.id = payment.id ``` 注意,在上面的查询与句中,`log.item.class` 和 `payment.class` 将涉及到完全不同的数据库中的列。