1、Hibernate HQL 语 法 大 全HQL: Hibernate查 询 语 言Hibernate配 备 了 一 种 非 常 强 大 的 查 询 语 言 , 这 种 语 言 看 上 去 很 像 SQL。但 是 不 要 被 语 法 结 构 上 的 相 似 所 迷 惑 , HQL是 非 常 有 意 识 的 被 设 计 为 完全 面 向 对 象 的 查 询 , 它 可 以 理 解 如 继 承 、 多 态 和 关 联 之 类 的 概 念 。1.大 小 写 敏 感 性 问 题除 了 Java类 与 属 性 的 名 称 外 , 查 询 语 句 对 大 小 写 并 不 敏 感 。 所 以S e L e
2、C T 与 s E L E c t 以 及 S E L E C T 是 相 同 的 , 但 是o r g . h i b e r n a t e . e g . F O O 并 不 等 价 于 o r g . h i b e r n a t e . e g . F o o 并 且f o o . b a r S e t 也 不 等 价 于 f o o . B A R S E T 。本 手 册 中 的 HQL关 键 字 将 使 用 小 写 字 母 . 很 多 用 户 发 现 使 用 完 全 大 写 的关 键 字 会 使 查 询 语 句 的 可 读 性 更 强 , 但 我 们 发 现 , 当 把 查
3、 询 语 句 嵌 入到 Java语 句 中 的 时 候 使 用 大 写 关 键 字 比 较 难 看 。2.from子 句Hibernate中 最 简 单 的 查 询 语 句 的 形 式 如 下 :from eg.Cat该 子 句 简 单 的 返 回 e g . C a t 类 的 所 有 实 例 。 通 常 我 们 不 需 要 使 用 类 的 全 限定 名 , 因 为 a u t o - i m p o r t ( 自 动 引 入 ) 是 缺 省 的 情 况 。 所 以 我 们 几 乎只 使 用 如 下 的 简 单 写 法 :from Cat大 多 数 情 况 下 , 你 需 要 指 定 一
4、个 别 名 , 原 因 是 你 可 能 需 要 在 查 询 语 句的 其 它 部 分 引 用 到 C a tfrom Cat as cat这 个 语 句 把 别 名 c a t 指 定 给 类 C a t 的 实 例 , 这 样 我 们 就 可 以 在 随 后 的 查询 中 使 用 此 别 名 了 。 关 键 字 a s 是 可 选 的 , 我 们 也 可 以 这 样 写 :from Cat cat子 句 中 可 以 同 时 出 现 多 个 类 , 其 查 询 结 果 是 产 生 一 个 笛 卡 儿 积 或 产 生 跨表 的 连 接 。from Formula, Parameterfrom F
5、ormula as form, Parameter as param查 询 语 句 中 别 名 的 开 头 部 分 小 写 被 认 为 是 实 践 中 的 好 习 惯 , 这 样 做 与Java变 量 的 命 名 标 准 保 持 了 一 致 (比 如 , d o m e s t i c C a t )。3.关 联 (Association)与 连 接 (Join)我 们 也 可 以 为 相 关 联 的 实 体 甚 至 是 对 一 个 集 合 中 的 全 部 元 素 指 定 一 个 别名 , 这 时 要 使 用 关 键 字 j o i n 。from Cat as cat inner join
6、cat.mate as mate left outer joincat.kittens as kittenfrom Cat as cat left join cat.mate.kittens as kittensfrom Formula form full join form.parameter param受 支 持 的 连 接 类 型 是 从 ANSI SQL中 借 鉴 来 的 。i n n e r j o i n ( 内 连 接 )l e f t o u t e r j o i n ( 左 外 连 接 )r i g h t o u t e r j o i n ( 右 外 连 接 )f u
7、l l j o i n (全 连 接 , 并 不 常 用 )语 句 i n n e r j o i n , l e f t o u t e r j o i n 以 及 r i g h t o u t e r j o i n 可 以 简写 。from Cat as cat join cat.mate as mate left join cat.kittens askitten还 有 , 一 个 “fetch“连 接 允 许 仅 仅 使 用 一 个 选 择 语 句 就 将 相 关 联 的 对 象或 一 组 值 的 集 合 随 着 他 们 的 父 对 象 的 初 始 化 而 被 初 始 化 , 这
8、种 方 法 在 使用 到 集 合 的 情 况 下 尤 其 有 用 , 对 于 关 联 和 集 合 来 说 , 它 有 效 的 代 替 了 映射 文 件 中 的 外 联 接 与 延 迟 声 明 ( lazy declarations) . 查 看 第 20.1节“ 抓 取 策 略 (Fetching strategies) ” 以 获 得 等 多 的 信 息 。from Cat as cat inner join fetch cat.mate left join fetchcat.kittens一 个 fetch连 接 通 常 不 需 要 被 指 定 别 名 , 因 为 相 关 联 的 对 象
9、不 应 当 被 用在 w h e r e 子 句 (或 其 它 任 何 子 句 )中 。 同 时 , 相 关 联 的 对 象 并 不 在 查 询的 结 果 中 直 接 返 回 , 但 可 以 通 过 他 们 的 父 对 象 来 访 问 到 他 们 。注 意 f e t c h 构 造 变 量 在 使 用 了 s c r o l l ( ) 或 i t e r a t e ( ) 函 数 的 查 询 中 是 不能 使 用 的 。 最 后 注 意 , 使 用 f u l l j o i n f e t c h 与 r i g h t j o i n f e t c h 是没 有 意 义 的 。如
10、果 你 使 用 属 性 级 别 的 延 迟 获 取 ( lazy fetching) ( 这 是 通 过 重 新 编写 字 节 码 实 现 的 ) , 可 以 使 用 f e t c h a l l p r o p e r t i e s 来 强 制Hibernate立 即 取 得 那 些 原 本 需 要 延 迟 加 载 的 属 性 ( 在 第 一 个 查 询中 ) 。from Document fetch all properties order by namefrom Document doc fetch all properties where lower(doc.name)like %
11、cats%4.select子 句s e l e c t 子 句 选 择 将 哪 些 对 象 与 属 性 返 回 到 查 询 结 果 集 中 . 考 虑 如 下 情况 :select mate from Cat as cat inner join cat.mate as mate该 语 句 将 选 择 m a t e s of other C a t s。 ( 其 他 猫 的 配 偶 ) 实 际 上 , 你 可以 更 简 洁 的 用 以 下 的 查 询 语 句 表 达 相 同 的 含 义 :select cat.mate from Cat cat查 询 语 句 可 以 返 回 值 为 任 何 类
12、 型 的 属 性 , 包 括 返 回 类 型 为 某 种 组 件(Component)的 属 性 :select cat.name from DomesticCat cat where cat.name likefri%select cust.name.firstName from Customer as cust查 询 语 句 可 以 返 回 多 个 对 象 和 ( 或 ) 属 性 , 存 放 在 O b j e c t 队 列 中 ,select mother, offspr, mate.name from DomesticCat as motherinner join mother.ma
13、te as mate left outer join mother.kittensas offspr或 存 放 在 一 个 L i s t 对 象 中 ,select new list(mother, offspr, mate.name) from DomesticCat asmother inner join mother.mate as mate left outer joinmother.kittens as offspr也 可 能 直 接 返 回 一 个 实 际 的 类 型 安 全 的 Java对 象 ,select new Family(mother, mate, offspr) f
14、rom DomesticCat asmother join mother.mate as mate left join mother.kittens asoffspr假 设 类 F a m i l y 有 一 个 合 适 的 构 造 函 数 .你 可 以 使 用 关 键 字 a s 给 “ 被 选 择 了 的 表 达 式 ” 指 派 别 名 :select max(bodyWeight) as max, min(bodyWeight) as min,count(*) as n from Cat cat这 种 做 法 在 与 子 句 s e l e c t n e w m a p 一 起 使 用
15、 时 最 有 用 :select new map( max(bodyWeight) as max, min(bodyWeight) asmin, count(*) as n ) from Cat cat该 查 询 返 回 了 一 个 M a p 的 对 象 , 内 容 是 别 名 与 被 选 择 的 值 组 成 的 名 -值 映射 。5.聚 集 函 数HQL查 询 甚 至 可 以 返 回 作 用 于 属 性 之 上 的 聚 集 函 数 的 计 算 结 果 :select avg(cat.weight), sum(cat.weight), max(cat.weight),count(cat) f
16、rom Cat cat受 支 持 的 聚 集 函 数 如 下 :a v g ( . . . ) , s u m ( . . . ) , m i n ( . . . ) , m a x ( . . . )c o u n t ( * )c o u n t ( . . . ) , c o u n t ( d i s t i n c t . . . ) , c o u n t ( a l l . . . )你 可 以 在 选 择 子 句 中 使 用 数 学 操 作 符 、 连 接 以 及 经 过 验 证 的 SQL函 数 :select cat.weight + sum(kitten.weight)
17、from Cat cat joincat.kittens kitten group by cat.id, cat.weightselect firstName| |initial| |upper(lastName) fromPerson关 键 字 d i s t i n c t 与 a l l 也 可 以 使 用 , 它 们 具 有 与 SQL相 同 的 语 义 .select distinct cat.name from Cat cat select count(distinctcat.name), count(cat) from Cat cat6.多 态 查 询一 个 如 下 的 查 询
18、语 句 :from Cat as cat不 仅 返 回 C a t 类 的 实 例 , 也 同 时 返 回 子 类 D o m e s t i c C a t 的 实 例 .Hibernate 可 以 在 f r o m 子 句 中 指 定 任 何 Java 类 或 接 口 . 查 询 会 返 回 继承 了 该 类 的 所 有 持 久 化 子 类 的 实 例 或 返 回 声 明 了 该 接 口 的 所 有 持 久 化 类的 实 例 。 下 面 的 查 询 语 句 返 回 所 有 的 被 持 久 化 的 对 象 :from java.lang.Object o接 口 N a m e d 可 能
19、被 各 种 各 样 的 持 久 化 类 声 明 :from Named n, Named m where n.name = m.name注 意 , 最 后 的 两 个 查 询 将 需 要 超 过 一 个 的 SQL S E L E C T .这 表 明 o r d e r b y子 句 没 有 对 整 个 结 果 集 进 行 正 确 的 排 序 . (这 也 说 明 你 不 能 对 这 样 的 查询 使 用 Q u e r y . s c r o l l ( ) 方 法 .)7.where子 句w h e r e 子 句 允 许 你 将 返 回 的 实 例 列 表 的 范 围 缩 小 . 如
20、果 没 有 指 定 别 名 ,你 可 以 使 用 属 性 名 来 直 接 引 用 属 性 :from Cat where name=Fritz如 果 指 派 了 别 名 , 需 要 使 用 完 整 的 属 性 名 :from Cat as cat where cat.name=Fritz返 回 名 为 ( 属 性 name等 于 ) Fritz的 C a t 类 的 实 例 。select foo from Foo foo, Bar bar where foo.startDate =bar.date将 返 回 所 有 满 足 下 面 条 件 的 F o o 类 的 实 例 : 存 在 如 下
21、的 b a r 的 一 个 实 例 ,其 d a t e 属 性 等 于 F o o 的 s t a r t D a t e 属 性 。 复 合 路 径 表 达 式 使 得 w h e r e 子句 非 常 的 强 大 , 考 虑 如 下 情 况 :from Cat cat where cat.mate.name is not null该 查 询 将 被 翻 译 成 为 一 个 含 有 表 连 接 ( 内 连 接 ) 的 SQL查 询 。 如 果 你 打算 写 像 这 样 的 查 询 语 句from Foo foo where foo.bar.baz.customer.address.city
22、 is notnull在 SQL中 , 你 为 达 此 目 的 将 需 要 进 行 一 个 四 表 连 接 的 查 询 。= 运 算 符 不 仅 可 以 被 用 来 比 较 属 性 的 值 , 也 可 以 用 来 比 较 实 例 :from Cat cat, Cat rival where cat.mate = rival.mateselect cat, mate from Cat cat, Cat mate where cat.mate = mate特 殊 属 性 ( 小 写 ) i d 可 以 用 来 表 示 一 个 对 象 的 唯 一 的 标 识 符 。 ( 你 也 可以 使 用 该 对
23、 象 的 属 性 名 。 )from Cat as cat where cat.id = 123 from Cat as cat wherecat.mate.id = 69第 二 个 查 询 是 有 效 的 。 此 时 不 需 要 进 行 表 连 接 !同 样 也 可 以 使 用 复 合 标 识 符 。 比 如 P e r s o n 类 有 一 个 复 合 标 识 符 , 它由 c o u n t r y 属 性 与 m e d i c a r e N u m b e r 属 性 组 成 。from bank.Person person where person.id.country = A
24、U andperson.id.medicareNumber = 123456from bank.Account account where account.owner.id.country =AU and account.owner.id.medicareNumber = 123456第 二 个 查 询 也 不 需 要 进 行 表 连 接 。同 样 的 , 特 殊 属 性 c l a s s 在 进 行 多 态 持 久 化 的 情 况 下 被 用 来 存 取 一 个 实例 的 鉴 别 值 ( discriminator value) 。 一 个 嵌 入 到 where子 句 中 的Java类
25、的 名 字 将 被 转 换 为 该 类 的 鉴 别 值 。from Cat cat where cat.class = DomesticCat你 也 可 以 声 明 一 个 属 性 的 类 型 是 组 件 或 者 复 合 用 户 类 型 ( 以 及 由 组 件 构成 的 组 件 等 等 ) 。 永 远 不 要 尝 试 使 用 以 组 件 类 型 来 结 尾 的 路 径 表 达 式( path-expression_r) ( 与 此 相 反 , 你 应 当 使 用 组 件 的 一 个 属 性 来 结尾 ) 。 举 例 来 说 , 如 果 s t o r e . o w n e r 含 有 一 个
26、 包 含 了 组 件 的 实体 a d d r e s sstore.owner.address.city / 正 确 store.owner.address / 错 误 !一 个 “ 任 意 ” 类 型 有 两 个 特 殊 的 属 性 i d 和 c l a s s , 来 允 许 我 们 按 照 下 面的 方 式 表 达 一 个 连 接 ( A u d i t L o g . i t e m 是 一 个 属 性 , 该 属 性 被 映 射 为 ) 。from AuditLog log, Payment payment where log.item.class =Payment and lo
27、g.item.id = payment.id注 意 , 在 上 面 的 查 询 与 句 中 , l o g . i t e m . c l a s s 和 p a y m e n t . c l a s s 将 涉及 到 完 全 不 同 的 数 据 库 中 的 列 。8.表 达 式在 w h e r e 子 句 中 允 许 使 用 的 表 达 式 包 括 大 多 数 你 可 以 在 SQL使 用 的 表 达 式种 类 :数 学 运 算 符 + , - , * , /二 进 制 比 较 运 算 符 = , = , , ! = , l i k e逻 辑 运 算 符 a n d , o r , n
28、o ti n , n o t i n , b e t w e e n , i s n u l l , i s n o t n u l l , i s e m p t y ,i s n o t e m p t y , m e m b e r o f and n o t m e m b e r o f“简 单 的 “ case, c a s e . . . w h e n . . . t h e n . . . e l s e . . .e n d ,和 “搜 索 “ case, c a s e w h e n . . . t h e n . . . e l s e . . .e n d字 符 串
29、 连 接 符 . . . | | . . . or c o n c a t ( . . . , . . . )c u r r e n t _ d a t e ( ) , c u r r e n t _ t i m e ( ) , c u r r e n t _ t i m e s t a m p ( )s e c o n d ( . . . ) , m i n u t e ( . . . ) , h o u r ( . . . ) , d a y ( . . . ) ,m o n t h ( . . . ) , y e a r ( . . . ) ,EJB-QL 3.0定 义 的 任 何 函
30、数 或 操 作 : s u b s t r i n g ( ) , t r i m ( ) ,l o w e r ( ) , u p p e r ( ) , l e n g t h ( ) , l o c a t e ( ) , a b s ( ) , s q r t ( ) ,b i t _ l e n g t h ( )c o a l e s c e ( ) 和 n u l l i f ( )c a s t ( . . . a s . . . ) , 其 第 二 个 参 数 是 某 Hibernate类 型 的 名字 , 以 及 e x t r a c t ( . . . f r o m
31、. . . ) , 只 要 ANSI c a s t ( ) 和e x t r a c t ( ) 被 底 层 数 据 库 支 持任 何 数 据 库 支 持 的 SQL标 量 函 数 , 比 如 s i g n ( ) , t r u n c ( ) ,r t r i m ( ) , s i n ( )JDBC参 数 传 入 ?命 名 参 数 : n a m e , : s t a r t _ d a t e , : x 1SQL 直 接 常 量 f o o , 6 9 , 1 9 7 0 - 0 1 - 0 1 1 0 : 0 0 : 0 1 . 0 Java p u b l i c s t
32、 a t i c f i n a l 类 型 的 常 量 e g . C o l o r . T A B B Y关 键 字 i n 与 b e t w e e n 可 按 如 下 方 法 使 用 :from DomesticCat cat where cat.name between A and Bfrom DomesticCat cat where cat.name in ( Foo, Bar, Baz )而 且 否 定 的 格 式 也 可 以 如 下 书 写 :from DomesticCat cat where cat.name not between A and Bfrom Domes
33、ticCat cat where cat.name not in ( Foo, Bar,Baz )同 样 , 子 句 i s n u l l 与 i s n o t n u l l 可 以 被 用 来 测 试 空 值 (null).在 Hibernate配 置 文 件 中 声 明 HQL“ 查 询 替 代 ( querysubstitutions) ” 之 后 , 布 尔 表 达 式 ( Booleans) 可 以 在 其 他 表 达 式中 轻 松 的 使 用 :true 1, false0系 统 将 该 HQL转 换 为 SQL语 句 时 , 该 设 置 表 明 将 用 字 符 1 和 0
34、来 取 代关 键 字 t r u e 和 f a l s e :from Cat cat where cat.alive = true你 可 以 用 特 殊 属 性 s i z e , 或 是 特 殊 函 数 s i z e ( ) 测 试 一 个 集 合 的 大 小 。from Cat cat where cat.kittens.size 0from Cat cat where size(cat.kittens) 0对 于 索 引 了 ( 有 序 ) 的 集 合 , 你 可 以 使 用 m i n i n d e x 与 m a x i n d e x 函 数 来引 用 到 最 小 与 最
35、大 的 索 引 序 数 。 同 理 , 你 可 以 使 用 m i n e l e m e n t 与m a x e l e m e n t 函 数 来 引 用 到 一 个 基 本 数 据 类 型 的 集 合 中 最 小 与 最 大 的 元素 。from Calendar cal where maxelement(cal.holidays) currentdatefrom Order order where maxindex(order.items) 100from Order order where minelement(order.items) 10000在 传 递 一 个 集 合 的 索
36、 引 集 或 者 是 元 素 集 (e l e m e n t s 与 i n d i c e s 函 数 ) 或者 传 递 一 个 子 查 询 的 结 果 的 时 候 , 可 以 使 用 SQL函 数 a n y , s o m e , a l l ,e x i s t s , i nselect mother from Cat as mother, Cat as kit where kit inelements(foo.kittens)select p from NameList list, Person p where p.name = someelements(list.names)f
37、rom Cat cat where exists elements(cat.kittens)from Player p where 3 all elements(p.scores)from Show show where fizard in indices(show.acts)注 意 , 在 Hibernate3种 , 这 些 结 构 变 量 - s i z e , e l e m e n t s , i n d i c e s ,m i n i n d e x , m a x i n d e x , m i n e l e m e n t , m a x e l e m e n t - 只
38、能 在 where子 句 中使 用 。一 个 被 索 引 过 的 ( 有 序 的 ) 集 合 的 元 素 (arrays, lists, maps)可 以 在其 他 索 引 中 被 引 用 ( 只 能 在 where子 句 中 ) :from Order order where order.items0.id = 1234select person from Person person, Calendar calendar wherecalendar.holidaysnational day = person.birthDay andperson.nationality.calendar =
39、calendarselect item from Item item, Order order where order.itemsorder.deliveredItemIndices0 = item and order.id = 11select item from Item item, Order order where order.itemsmaxindex(order.items) = item and order.id = 11在 中 的 表 达 式 甚 至 可 以 是 一 个 算 数 表 达 式 。select item from Item item, Order order whe
40、re order.itemssize(order.items) - 1 = item对 于 一 个 一 对 多 的 关 联 ( one-to-many association) 或 是 值 的 集 合 中的 元 素 , HQL也 提 供 内 建 的 i n d e x ( ) 函 数 ,select item, index(item) from Order order join order.itemsitem where index(item) 100 order by count(kitten) asc,sum(kitten.weight) desc注 意 g r o u p b y 子 句
41、 与 o r d e r b y 子 句 中 都 不 能 包 含 算 术 表 达 式( arithmetic expression_rs) .11.子 查 询对 于 支 持 子 查 询 的 数 据 库 , Hibernate支 持 在 查 询 中 使 用 子 查 询 。 一 个 子 查 询 必 须 被 圆 括 号 包 围起 来 ( 经 常 是 SQL聚 集 函 数 的 圆 括 号 ) 。 甚 至 相 互 关 联 的 子 查 询 ( 引 用 到 外 部 查 询 中 的 别 名 的 子查 询 ) 也 是 允 许 的 。from Cat as fatcat where fatcat.weight (
42、 selectavg(cat.weight) from DomesticCat cat )from DomesticCat as cat where cat.name = some ( selectname.nickName from Name as name )from Cat as cat where not exists ( from Cat as mate wheremate.mate = cat )from DomesticCat as cat where cat.name not in ( selectname.nickName from Name as name )在 selec
43、t列 表 中 包 含 一 个 表 达 式 以 上 的 子 查 询 , 你 可 以 使 用 一 个 元 组 构 造 符 ( tupleconstructors) :from Cat as cat where not ( cat.name, cat.color ) in ( selectcat.name, cat.color from DomesticCat cat )注 意 在 某 些 数 据 库 中 ( 不 包 括 Oracle与 HSQL) , 你 也 可 以 在 其 他 语 境 中 使 用 元 组 构 造 符 , 比 如查 询 用 户 类 型 的 组 件 与 组 合 :from Perso
44、n where name = (Gavin, A, King)该 查 询 等 价 于 更 复 杂 的 :from Person where name.first = Gavin and name.initial = Aand name.last = King)有 两 个 很 好 的 理 由 使 你 不 应 当 作 这 样 的 事 情 : 首 先 , 它 不 完 全 适 用 于 各 个 数 据 库 平 台 ; 其 次 ,查 询 现 在 依 赖 于 映 射 文 件 中 属 性 的 顺 序 。12.HQL示 例Hibernate查 询 可 以 非 常 的 强 大 与 复 杂 。 实 际 上 , Hi
45、bernate的 一 个 主 要 卖 点 就 是 查 询 语 句 的 威力 。 这 里 有 一 些 例 子 , 它 们 与 我 在 最 近 的 一 个 项 目 中 使 用 的 查 询 非 常 相 似 。 注 意 你 能 用 到 的 大多 数 查 询 比 这 些 要 简 单 的 多 !下 面 的 查 询 对 于 某 个 特 定 的 客 户 的 所 有 未 支 付 的 账 单 , 在 给 定 给 最 小 总 价 值 的 情 况 下 , 返 回 订单 的 id, 条 目 的 数 量 和 总 价 值 , 返 回 值 按 照 总 价 值 的 结 果 进 行 排 序 。 为 了 决 定 价 格 , 查 询
46、 使 用了 当 前 目 录 。 作 为 转 换 结 果 的 SQL查 询 , 使 用 了 O R D E R , O R D E R _ L I N E , P R O D U C T ,C A T A L O G和 P R I C E 库 表 。select order.id, sum(price.amount), count(item) from Order asorder join order.lineItems as item join item.product asproduct, Catalog as catalog join catalog.prices as price whe
47、reorder.paid = false and order.customer = :customer andprice.product = product and catalog.effectiveDate = all ( select cat.effectiveDatefrom Catalog as cat where cat.effectiveDate :minAmount order bysum(price.amount) desc这 简 直 是 一 个 怪 物 ! 实 际 上 , 在 现 实 生 活 中 , 我 并 不 热 衷 于 子 查 询 , 所 以 我 的 查 询 语 句 看
48、起 来更 像 这 个 :select order.id, sum(price.amount), count(item) from Order asorder join order.lineItems as item join item.product asproduct, Catalog as catalog join catalog.prices as price whereorder.paid = false and order.customer = :customer andprice.product = product and catalog = :currentCatalog gro
49、up byorder having sum(price.amount) :minAmount order bysum(price.amount) desc下 面 一 个 查 询 计 算 每 一 种 状 态 下 的 支 付 的 数 目 , 除 去 所 有 处 于 A W A I T I N G _ A P P R O V A L 状 态 的支 付 , 因 为 在 该 状 态 下 当 前 的 用 户 作 出 了 状 态 的 最 新 改 变 。 该 查 询 被 转 换 成 含 有 两 个 内 连 接 以及 一 个 相 关 联 的 子 选 择 的 SQL查 询 , 该 查 询 使 用 了 表 P A Y M E N T , P A Y M E N T _ S T A T U S 以 及P A Y M E N T _ S T A T U S _ C H A N G E。select count(payment), status.name from Payment as paymentjoin payment.currentStatus as status joinpayment.statusChanges