## koa3-demo 当前支持功能: - [ ] 路由 - [x] 日志 - [ ] 权限 - [x] 数据库 - [ ] 缓存 - [ ] 界面 - [ ] 定时任务 - [ ] htmx ### 数据库查询缓存(QueryBuilder 扩展) 为 Knex QueryBuilder 增加了内存级缓存能力,支持 TTL、自定义 key、只读/只写、按前缀失效与全局工具访问。默认 key 为查询的 `toString()`,也可通过 `cacheAs()` 指定。 可用方法: - `cache(ttlMs?)`: 读取缓存,不存在则执行 SQL 并写入缓存;可选 TTL(毫秒)。 - `cacheAs(customKey)`: 为当前查询设置自定义缓存 key(链式,返回 builder)。 - `cacheSet(value, ttlMs?)`: 手动写入当前查询 key 的缓存,返回写入的值。 - `cacheGet()`: 仅从缓存读取当前查询 key 的值(不命中则返回 `undefined`,不会执行 SQL)。 - `cacheInvalidate()`: 使当前查询 key 的缓存失效(删除)。 - `cacheInvalidateByPrefix(prefix)`: 按前缀批量失效。 全局工具(命名导出 `DbQueryCache`,便于在查询构建器之外操作缓存): - `get/set/has/delete/clear/clearByPrefix/stats()` 示例: ```js import db, { DbQueryCache } from "./src/db/index.js" // 1) 简单缓存 5 秒 const u1 = await db("users").where({ id: 1 }).first().cache(5000) // 2) 自定义 key + 只读命中 const key = "users:count:active" const count = await db("users").where({ active: 1 }).count({ c: "*" }).cacheAs(key).cache(10000) const cachedOnly = db("users").where({ active: 1 }).cacheAs(key).cacheGet() // 命中则返回值,不命中为 undefined // 3) 手动写入/覆盖缓存 15 秒 db("users").where({ active: 1 }).cacheAs(key).cacheSet([{ c: 123 }], 15000) // 4) 单点或前缀失效 db("users").where({ active: 1 }).cacheAs(key).cacheInvalidate() db.queryBuilder().cacheInvalidateByPrefix("users:") // 5) 全局操作 DbQueryCache.clearByPrefix("users:") const stats = DbQueryCache.stats() // { size, valid, expired } ``` 注意: - 该实现为进程内内存缓存,适合单实例与读多写少场景;多实例下需用外部缓存(如 Redis)替换/扩展。 - TTL 为可选,未设置则永久有效,直到被失效或进程重启。 - 自定义 key 建议使用明确的命名空间前缀(如 `users:`、`site:`),以便使用前缀批量失效。