不是 SQL 替换
Ebean ORM 查询适用于典型的 OLTP 查询用例,但有许多查询可以用 SQL 编写,而 ORM 不太适合,特别是在报告和 OLAP 领域。递归 SQL 查询目前也不受很好支持。
Ebean ORM 查询专注于 OLTP。不要忘记在适当的时候使用 SQL。
对于 Ebean,重点是将 ORM 查询用于 OLTP 用例。计划不是扩展 ORM 查询语言,而是通过 RawSql
、SqlQuery
和即将到来/期望的 JOOQ
集成与 SQL 进行良好集成。
对象图构造
将 ORM 查询视为对象图构造可能很有用。也就是说,当你创建 ORM 查询时,它是一个定义,说明要加载对象图的哪一部分以及需要应用哪些过滤器/谓词。
加载
对于 Ebean,select()
和 fetch()
控制要加载对象图的哪一部分。select()
适用于对象图的根级别,而 fetch()
适用于对象图叶子。在更高级的情况下,FetchConfig
可用于控制图的哪些部分被急切/延迟加载,以及图的该部分是从数据库、L2 缓存还是 L3 缓存/文档存储加载的。
对象图的某些部分可以从 L2 缓存或 L3/文档存储加载
加载 - 查询调整
调整 ORM 查询以获得最佳性能归结为
- 要加载哪些属性(仅加载给定用例所需的属性)
- 对象图的哪些部分要急切或延迟加载
- 从数据库、L2 缓存或 L3 文档存储中加载对象图的哪些部分
- 根本不执行查询,而是使用 L2 查询缓存
- 根本不执行查询,而是使用 L3 文档存储
加载 - 自动调整
Ebean 的自动调整功能能够分析应用程序使用对象图的哪些部分,然后对 ORM 查询的“加载什么”部分提供自动调整。也就是说,自动调整可以建议 ORM 查询的 select()
和 fetch()
部分应该是什么,以便仅从数据库中获取所需内容(减少查询的网络和数据库成本)并最大程度地减少延迟加载。
Ebean 可以自动调整“加载什么”
谓词
where()
子句是定义查询谓词的地方。这实际上是“应用程序逻辑”,不会因“调整”目的等而改变。
谓词 - 类型安全
Ebean 的类型安全查询扩展旨在提供构建查询谓词的类型安全方式。因此,它不专注于通过 select() 和 fetch() 子句提供“获取什么”的类型安全性(相反,预计这些子句主要由自动调整定义)。
自动联接
Ebean 的查询语言设计为对于查询,您不必明确指定联接,而是定义“加载什么”和“谓词”。Ebean 会找出支持查询的加载和谓词方面所需的联接。某些 SQL 联接可以由加载和谓词共享,而某些联接则不能,外部联接会沿着给定的对象路径“继承”等。Ebean 会根据加载和谓词中涉及的关系/路径的基数和可选项性来添加联接和联接类型。
这种方法的缺点是目前无法轻松指定使用“自联接”的谓词,但此问题将得到解决,而 Ebean 自动确定联接的这种方法有一些非常显着的好处。
避免笛卡尔积
Ebean 绝不会生成 SQL 笛卡尔积。无论您的 ORM 查询多么复杂或庞大,Ebean 都不会生成 SQL 笛卡尔积,而是将查询分解为多个 SQL 查询。
FirstRows MaxRows
FirstRows
和 MaxRows
始终会在您的 ORM 查询中起作用。也就是说,firstRows/maxRows 适用于关系行(而不是对象),Ebean 会根据需要自动将 ORM 查询分解为多个 SQL 查询,以便 firstRows/maxRows 按预期工作。
任意复杂的图
无论您的 ORM 查询的对象图多么复杂或嵌套,Ebean 都可以以非常有效的方式构建它。更具体地说,单个 SQL 查询最多可以包含一个 OneToMany 或 ManyToMany 关系“路径”(不会产生我们真正想要避免的 SQL 笛卡尔积)。Ebean 会将 ORM 查询分解为多个 SQL 查询,每个 SQL 查询在其获取中都有一个 OneToMany/ManyToMany 关系(每个 SQL 查询尽可能热切/大,而不会变成笛卡尔积)。
Ebean 处理所有获取路径,确定哪些路径包含 OneToMany 或 ManyToMany 关系。查询“分解”可以通过使用 FetchConfig
手动控制,但如果尚未完成此操作或尚未涵盖所有必需的关系,则 Ebean 会根据这些“包含多关系的路径”自动分解查询。
术语
加载上下文
“加载上下文”是一个内部 Ebean 功能,具有非常重要的作用。它支持执行辅助查询并提供
- 批量延迟加载
- 查询联接(急切辅助查询)
- 从原始查询到任何/所有辅助查询传播键查询状态。
本质上,加载上下文提供了一种批量加载复杂图表的机制。
原始查询
“原始查询”是 Ebean 术语,用于指构建对象图表时执行的原始 SQL 查询。其他 SQL “辅助查询”可以执行并与“原始查询”相关联。
摘要日志记录
在摘要日志记录中,有一个 origin
属性,这是一个可用于链接原始查询和辅助查询的键。
txn[1012] FindBean type[Order] origin[B0dP9E.DWeHD4.5WUnB] ...
辅助查询
“辅助查询”是 Ebean 用于与先前执行的“原始查询”相关的 SQL 查询的术语。这些辅助查询可以由于延迟加载而执行,或者因为单个 ORM 查询被手动或自动分解为多个 SQL 查询(为了避免笛卡尔积并支持 firstRows/maxRows)。
摘要日志记录
在摘要日志记录中,mode
和 origin
属性可用于识别哪些 SQL 查询是“辅助查询”,以及它们所关联的原始查询。例如,此日志记录可用于识别过度的延迟加载 (N + 1)。
mode
:对于延迟加载查询为 +lazy,对于查询联接/急切加载为 +queryorigin
:此键将辅助查询链接回原始查询
txn[1012] FindBean type[Order] origin[B0dP9E.DWeHD4.5WUnB] ...
...
txn[1016] FindMany mode[+lazy] type[Customer] origin[B0dP9E.DWeHD4.5WUnB] ...
...
txn[1017] FindMany mode[+lazy] type[Address] origin[B0dP9E.DWeHD4.5WUnB] ...