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" ) type Category struct { ID int64 `db:"id"` Slug string `db:"slug"` Title string `db:"title"` Sort int `db:"sort"` } type CategoryModel interface { FindAll(ctx context.Context) ([]*Category, error) } type defaultCategoryModel struct { db *sqlx.DB cache *cache.Cache } 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"). From("public.categories"). Where(sq.GtOrEq{"sort": 1}). OrderBy("sort ASC", "id ASC"). Limit(10). PlaceholderFormat(sq.Dollar). ToSql() if err != nil { return nil, fmt.Errorf("squirrel 出错: %w", err) } rows := make([]*Category, 0) err = m.db.SelectContext(ctx, &rows, query, args...) if err != nil { return nil, fmt.Errorf("数据库查询出错: %w", 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 }