一,大小写敏感问题
除了Java类与属性的名称外,查询语句对大小写并不敏感。 所以 SeLeCT
与 sELEct
以及 SELECT
是相同的,但是 org.hibernate.eg.FOO
并不等价于 org.hibernate.eg.Foo
并且 foo.barSet
也不等价于 foo.BARSET
。
二,from子句
Hibernate中最简单的查询语句的形式如下:
from eg.Cat
该子句简单的返回eg.Cat
类的所有实例。 通常我们不需要使用类的全限定名, 因为 auto-import
(自动引入) 是缺省的情况。 所以我们几乎只使用如下的简单写法:
from Cat
大多数情况下, 你需要指定一个别名, 原因是你可能需要 在查询语句的其它部分引用到Cat
from Cat as cat
这个语句把别名cat
指定给类Cat
的实例, 这样我们就可以在随后的查询中使用此别名了。 关键字as
是可选的,我们也可以这样写:
from Cat cat
子句中可以同时出现多个类, 其查询结果是产生一个笛卡儿积或产生跨表的连接。
from Formula, Parameter
from Formula as form, Parameter as param
查询语句中别名的开头部分小写被认为是实践中的好习惯, 这样做与Java变量的命名标准保持了一致 (比如,domesticCat
)。
三,select子句
select
子句选择将哪些对象与属性返 回到查询结果集中. 考虑如下情况:
select mate from Cat as cat inner join cat.mate as mate
该语句将选择mate
s of other Cat
s。(其他猫的配偶) 实际上, 你可以更简洁的用以下的查询语句表达相同的含义:
select cat.mate from Cat cat
查询语句可以返回值为任何类型的属性,包括返回类型为某种组件(Component)的属性:
select cat.name from DomesticCat cat where cat.name like 'fri%'
select cust.name.firstName from Customer as cust
查询语句可以返回多个对象和(或)属性,存放在 Object[]
队列中,
select mother, offspr, mate.name from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
或存放在一个List
对象中,
select new list(mother, offspr, mate.name) from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
也可能直接返回一个实际的类型安全的Java对象,
select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr
假设类Family
有一个合适的构造函数.
你可以使用关键字as
给“被选择了的表达式”指派别名:
select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n from Cat cat
这种做法在与子句select new map
一起使用时最有用:
select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n ) from Cat cat
该查询返回了一个Map
的对象,内容是别名与被选择的值组成的名-值映射。
四,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
将涉及到完全不同的数据库中的列。