SQL 日志与追踪
调试 ORM 行为的核心手段是看生成的 SQL。newSqlClient 的 sqlLogger 选项控制打印形态:
const client = newSqlClient(driver, {
sqlLogger: {
pretty: true, // 换行缩进美化
parameter: "PLACEHOLDER", // 参数呈现方式
},
})
parameter 三种呈现
| 值 | 效果 |
|---|---|
PLACEHOLDER(默认) | 参数位显示 ?,参数值另行可见 |
COMMENT | SQL 后追加注释(-- $1 = 79.0) |
INLINE | 参数值直接内联进 SQL 文本(调试友好,注意别在生产开) |
沙盒里怎么用
沙盒每次运行都自动捕获 SQL 并显示在结果面板的 SQL 追踪区(等价于恒开日志)。演示:跑一次嵌套取形查询,看主查询与 loadAssociation 两段的真实 SQL:
// ① 模型(完整可运行版见工作区)
import { model, prop, dto } from '@ts-grm/core'
import { sqlClient } from './infra/sql-client'
const BookStore = model("BookStore", "id", class {
id = prop.i64()
name = prop.str(100)
})
const Book = model("Book", "id", class {
id = prop.i64()
name = prop.str(50)
edition = prop.i32()
price = prop.num(10, 2)
store = prop.m2o(BookStore).nullable()
})
// ② 嵌套取形:SQL 追踪会显示 主查询 + loadAssociation 两段
const rows = await sqlClient.createQuery(Book, (q, book) => {
q.orderBy(book.name)
return q.select(book.fetch(dto.view(Book, c => [
c.id,
c.name,
c.store.with(c => [c.id, c.name]),
])))
}).fetchList()
console.log(rows.map(r => `${r.name} @ ${r.store?.name}`).join('\n'))
阅读 SQL 追踪的要点:
- 看第二段的 IN 列表——批加载按主查询收集的 key 合并,恒两段;
- 对照预期形状——视图选了哪些列、嵌套展开成几段,都一目了然;
- 怀疑方言/优化问题时,把这段 SQL 复制到你的数据库 EXPLAIN。
生产建议
- 生产一般
pretty: false+PLACEHOLDER,避免日志膨胀; - 连接驱动的原生日志(
pg的 pool 事件等)与sqlLogger是两层,按需取舍。