feat(lyra): 为分类查询添加缓存并同步项目约定

- 实现分类列表缓存查询与故障降级
- 统一缓存键命名
- 同步日志、响应、依赖组装及测试约定
- 移除 postgres 占位目录
This commit is contained in:
2026-10-20 17:42:41 +08:00
parent bef30be3fe
commit 97b26635fa
8 changed files with 69 additions and 10 deletions
+5 -1
View File
@@ -2,5 +2,9 @@
- 承载数据结构定义与数据访问:使用 Squirrel/SQL 构造查询、sqlx 执行与映射结果,驱动为 pgx stdlib。
- SQL 与查询逻辑显式写在这一层,不使用 ORM 自动持久化。
- 支持在 service 传入的同一事务内执行操作。
- 事务边界由 service 决定;需要同一事务时由 service 传入事务执行。这是设计目标,当前没有现成的事务接口封装。
- 查询缓存采用 cache-aside:先读缓存,命中直接返回(空列表也可命中);未命中或缓存读取失败时回源数据库。
- 仅数据库查询成功后回填缓存;数据库失败不回填。缓存读写故障只记录日志并降级,不改变数据库查询结果。
- 缓存键使用 `internal/pkg/constant` 中的常量,遵循根 `AGENTS.md` 的 Redis 缓存键约定。
- 未来写路径应在事务提交后使相关缓存失效;当前 `cache` 包没有删除接口,失效策略属于后续设计约束。
- 使用标准 context.Context,不依赖 Gin,也不依赖 internal/api 的 DTO。
+22 -1
View File
@@ -3,7 +3,11 @@ package model
import (
"context"
"fmt"
"time"
"lyra/internal/cache"
"lyra/internal/pkg/constant"
"lyra/internal/util"
sq "github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
@@ -27,7 +31,17 @@ type defaultCategoryModel struct {
func NewCategoryModel(db *sqlx.DB, cache *cache.Cache) CategoryModel {
return &defaultCategoryModel{db: db, cache: cache}
}
const categoryListCacheTTL = 5 * time.Minute
func (m *defaultCategoryModel) FindAll(ctx context.Context) ([]*Category, error) {
cached, hit, err := m.cache.Get[[]*Category](ctx, constant.CategoryListCacheKey)
if err != nil {
util.Logger(ctx).Error("读取分类列表缓存失败", "key", constant.CategoryListCacheKey, "error", err)
}
if hit {
return cached, nil
}
query, args, err := sq.
Select("id", "slug", "title", "sort").
@@ -45,5 +59,12 @@ func (m *defaultCategoryModel) FindAll(ctx context.Context) ([]*Category, error)
if err != nil {
return nil, fmt.Errorf("数据库查询出错: %w", err)
}
return rows, err
if err := m.cache.Set(ctx, cache.Entry[[]*Category]{
Key: constant.CategoryListCacheKey,
Value: rows,
TTL: categoryListCacheTTL,
}); err != nil {
util.Logger(ctx).Error("写入分类列表缓存失败", "key", constant.CategoryListCacheKey, "error", err)
}
return rows, nil
}