Rust in Everything
基于 sea-orm 2.0.4

查询

一次 find 的全过程 把 find_by_id(1).one(&db) 从头走到尾,这一部分把查询主线的两端展开。前一端是 Select<E>:filter、order_by、limit、join 等方法都只是往同一个 sea-query SelectStatement 里加子句(query/ 目录,约 0.7 万行)。后一端是执行:Selector<S> 用类型参数 S 决定把一行读成什么,find_with_related 在内存里合并,Paginator / Cursor 改写原查询再发(executor/ 目录,约 1.1 万行)。

  1. Select 与过滤:Select<E> 只是一个 SelectStatement 加一个类型标记;QueryFilter / QuerySelect / QueryOrder 的每个方法改一个子句,多次 filter 用 AND 连接,one() 会覆盖你设的 LIMIT;lock 系列生成 FOR UPDATE / SKIP LOCKED;into_model / into_tuple / into_values / into_json 发出同一条 SQL,只换 SelectorTrait。
  2. join 与 find_related:find_also_related 是一条 LEFT JOIN,列名加 A_ / B_ 前缀,每行拆成一对;find_with_related 是同一条 join 加 ORDER BY 父表主键,再按父表主键用 HashMap 合并,limit 限制的是 join 后的行;find_related 从一个 Model 出发、has_related 生成 EXISTS 子查询。
  3. Loader 与 N+1:不用 join,先查父表、再按收集到的键查子表;LoaderTrait 和 2.0 的 Entity Loader 各发几条语句。
  4. 部分列与自定义结果:FromQueryResult、DerivePartialModel、into_tuple 怎么只取一部分列、按什么规则把列对上字段。
  5. 分页与游标:Paginator 的计数查询和 LIMIT / OFFSET,Cursor 按键值翻页,数据变化时两者的区别。
flowchart TB
  find["Entity::find"] --> sel["Select E"]
  sel -->|"filter / order_by / limit"| sel
  sel -->|find_also_related| two["SelectTwo"]
  sel -->|find_with_related| many["SelectTwoMany"]
  sel -->|"into_model 等"| selector["Selector S"]
  two --> selector
  many -->|"all + consolidate"| res["Vec 父 子列表"]
  selector --> rows["一行 → S::Item"]
  sel -->|paginate| pag["Paginator"]
  sel -->|load_many| loader["Loader"]

关系本身(RelationDef、Related、Linked、join / join_rev 生成的 ON 条件)在 关系;条件和值怎么变成 Expr、什么变成 $N 在 列与值 和 QueryBuilder 与参数。

💬 关联讨论

发起讨论
加载中...