保存并回读(save + view)
save 的第三个(关键)选项是 view——带上它,保存后立即用该视图回读刚写入的内容。
于是一次调用同时拿到两样东西:写入计数(affected)与写后形状(data)。
结果形态(上游类型测试口径)
// ① SaveResult:affected 按关联路径计数,$total 汇总
// {
// affected: {
// $total: number,
// "childNodes": number,
// "childNodes.childNodes": number,
// "childNodes.tags": number,
// },
// }
affected.$total:本次保存累计触达的行数(根 + 各层关联);- 其余键:每条内嵌关联路径各自的触达行数——
save.test-d.ts明确要求$total与每个关联路径都出现在结果里; - 单条载荷 →
data是单个对象;数组载荷(save(input, [obj1, obj2], …))→data是数组。
写后回读
// ② save + view:写根、回读整棵形状
// const BookView = dto.view(Book, c => [
// c.id,
// c.name,
// c.store.with(c => [c.id, c.name]),
// c.authors.with(c => [c.id, c.name]),
// ])
//
// const result = await sqlClient.save(
// BookInput,
// [{ id: 10n, name: "新书 A", authors: [{ id: 5n }] }],
// {
// root: "UPSERT",
// associated: { "authors": "APPEND_IF_ABSENT" },
// view: BookView,
// },
// )
// console.log(result.affected) // { $total, authors }
// console.log(result.data) // 写后按 BookView 回读的数组
- 回读用查询端熟悉的 view 语法——
save与createQuery共享同一个dto.view; - 「保存并回读」把 before → act → after 收进一条调用:act 是 save,after 是 data,
affected是旁证,DB 抽屉随时可以再瞄一眼真实表数据——四方互证,一文不差。
单条与批量
save 的第二参既收单对象也收数组(上游为其准备了 4 个重载:单/多 × 带/不带 view):
| 第二参 | 带 view? | 返回 data |
|---|---|---|
obj | 否 | 无 data,仅 affected |
obj | 是 | data: T(单对象) |
obj[] | 否 | 无 data,仅 affected |
obj[] | 是 | data: T[](数组) |
批量 + root 模式自由组合:save(Input, [a, b, c], { root: "UPSERT", view })——
一批幂等写入 + 一次回读,前端拿回去就能直接渲染。
小结
affected:$total+ 每路径计数,回答「这次写动了多少行/哪些层」;view:复用查询视图做写后回读,data直接是最终形状;- 单/批量切换只改第二参,其余配置不变。