查询
一次 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 万行)。
- 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。 - 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子查询。 - Loader 与 N+1:不用 join,先查父表、再按收集到的键查子表;
LoaderTrait和 2.0 的 Entity Loader 各发几条语句。 - 部分列与自定义结果:
FromQueryResult、DerivePartialModel、into_tuple怎么只取一部分列、按什么规则把列对上字段。 - 分页与游标:
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 与参数。
💬 关联讨论
发起讨论加载中...