package examples import ( "context" "time" "go.uber.org/zap" "gorm.io/gorm" "tyapi-server/internal/domains/user/entities" "tyapi-server/internal/domains/user/repositories" "tyapi-server/internal/domains/user/repositories/queries" "tyapi-server/internal/shared/database" "tyapi-server/internal/shared/interfaces" ) // ModernCachedUserRepository 现代化的用户仓储(使用新缓存方案) type ModernCachedUserRepository struct { *database.CachedBaseRepositoryImpl } // 编译时检查接口实现 var _ repositories.UserRepository = (*ModernCachedUserRepository)(nil) // NewModernCachedUserRepository 创建现代化缓存用户仓储 func NewModernCachedUserRepository(db *gorm.DB, logger *zap.Logger) repositories.UserRepository { return &ModernCachedUserRepository{ CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, "users"), } } // ================ Repository[T] 接口实现 ================ // Create 创建用户(自动失效相关缓存) func (r *ModernCachedUserRepository) Create(ctx context.Context, user entities.User) (entities.User, error) { r.GetLogger().Info("创建用户", zap.String("phone", user.Phone)) // 使用基础创建方法,GORM插件会自动处理缓存失效 err := r.CreateEntity(ctx, &user) return user, err } // GetByID 根据ID获取用户(自动缓存30分钟) func (r *ModernCachedUserRepository) GetByID(ctx context.Context, id string) (entities.User, error) { var user entities.User // 使用智能缓存查询,自动缓存30分钟 err := r.SmartGetByID(ctx, id, &user) return user, err } // Update 更新用户(自动失效相关缓存) func (r *ModernCachedUserRepository) Update(ctx context.Context, user entities.User) error { r.GetLogger().Info("更新用户", zap.String("user_id", user.ID)) // 使用基础更新方法,GORM插件会自动处理缓存失效 return r.UpdateEntity(ctx, &user) } // CreateBatch 批量创建用户 func (r *ModernCachedUserRepository) CreateBatch(ctx context.Context, users []entities.User) error { r.GetLogger().Info("批量创建用户", zap.Int("count", len(users))) return r.CreateBatchEntity(ctx, &users) } // GetByIDs 根据ID列表获取用户(带缓存) func (r *ModernCachedUserRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.User, error) { var users []entities.User // 使用批量缓存查询,缓存15分钟 err := r.BatchGetWithCache(ctx, ids, &users, 15*time.Minute) return users, err } // UpdateBatch 批量更新用户 func (r *ModernCachedUserRepository) UpdateBatch(ctx context.Context, users []entities.User) error { r.GetLogger().Info("批量更新用户", zap.Int("count", len(users))) return r.UpdateBatchEntity(ctx, &users) } // DeleteBatch 批量删除用户 func (r *ModernCachedUserRepository) DeleteBatch(ctx context.Context, ids []string) error { r.GetLogger().Info("批量删除用户", zap.Strings("ids", ids)) return r.DeleteBatchEntity(ctx, ids, &entities.User{}) } // List 获取用户列表(智能缓存) func (r *ModernCachedUserRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.User, error) { var users []entities.User // 使用智能列表查询,根据查询复杂度自动选择缓存策略 err := r.SmartList(ctx, &users, options) return users, err } // ================ BaseRepository 接口实现 ================ // Delete 删除用户 func (r *ModernCachedUserRepository) Delete(ctx context.Context, id string) error { return r.DeleteEntity(ctx, id, &entities.User{}) } // Exists 检查用户是否存在(带缓存) func (r *ModernCachedUserRepository) Exists(ctx context.Context, id string) (bool, error) { return r.ExistsEntity(ctx, id, &entities.User{}) } // Count 统计用户数量(智能缓存) func (r *ModernCachedUserRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) { var count int64 // 计算缓存TTL cacheTTL := 10 * time.Minute if options.Search != "" { cacheTTL = 2 * time.Minute // 搜索查询缓存时间更短 } err := r.CountWithCache(ctx, &count, cacheTTL, &entities.User{}, "", nil) return count, err } // SoftDelete 软删除用户 func (r *ModernCachedUserRepository) SoftDelete(ctx context.Context, id string) error { return r.SoftDeleteEntity(ctx, id, &entities.User{}) } // Restore 恢复用户 func (r *ModernCachedUserRepository) Restore(ctx context.Context, id string) error { return r.RestoreEntity(ctx, id, &entities.User{}) } // ================ 业务专用方法(使用新缓存API) ================ // GetByPhone 根据手机号获取用户(缓存15分钟) func (r *ModernCachedUserRepository) GetByPhone(ctx context.Context, phone string) (*entities.User, error) { var user entities.User // 使用智能字段查询,自动缓存15分钟 err := r.SmartGetByField(ctx, &user, "phone", phone, 15*time.Minute) if err != nil { return nil, err } return &user, nil } // GetByUsername 根据用户名获取用户(缓存15分钟) func (r *ModernCachedUserRepository) GetByUsername(ctx context.Context, username string) (*entities.User, error) { var user entities.User err := r.SmartGetByField(ctx, &user, "username", username, 15*time.Minute) if err != nil { return nil, err } return &user, nil } // GetByUserType 根据用户类型获取用户列表 func (r *ModernCachedUserRepository) GetByUserType(ctx context.Context, userType string) ([]*entities.User, error) { var users []*entities.User err := r.FindWithCache(ctx, &users, 30*time.Minute, "user_type = ?", userType) return users, err } // ListUsers 获取用户列表(带分页和筛选) func (r *ModernCachedUserRepository) ListUsers(ctx context.Context, query *queries.ListUsersQuery) ([]*entities.User, int64, error) { var users []*entities.User var total int64 // 构建查询条件 db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 15*time.Minute) // 应用筛选条件 if query.Phone != "" { db = db.Where("phone LIKE ?", "%"+query.Phone+"%") } if query.StartDate != "" { db = db.Where("created_at >= ?", query.StartDate) } if query.EndDate != "" { db = db.Where("created_at <= ?", query.EndDate) } // 统计总数 if err := db.Model(&entities.User{}).Count(&total).Error; err != nil { return nil, 0, err } // 应用分页 offset := (query.Page - 1) * query.PageSize if err := db.Offset(offset).Limit(query.PageSize).Find(&users).Error; err != nil { return nil, 0, err } return users, total, nil } // ValidateUser 验证用户登录 func (r *ModernCachedUserRepository) ValidateUser(ctx context.Context, phone, password string) (*entities.User, error) { // 登录验证不使用缓存,确保安全性 var user entities.User db := r.WithoutCache().GetDB(ctx) err := db.Where("phone = ? AND password = ?", phone, password).First(&user).Error if err != nil { return nil, err } return &user, nil } // UpdateLastLogin 更新最后登录时间 func (r *ModernCachedUserRepository) UpdateLastLogin(ctx context.Context, userID string) error { now := time.Now() return r.GetDB(ctx).Model(&entities.User{}). Where("id = ?", userID). Updates(map[string]interface{}{ "last_login_at": &now, "updated_at": now, }).Error } // UpdatePassword 更新密码 func (r *ModernCachedUserRepository) UpdatePassword(ctx context.Context, userID string, newPassword string) error { return r.GetDB(ctx).Model(&entities.User{}). Where("id = ?", userID). Update("password", newPassword).Error } // CheckPassword 检查密码 func (r *ModernCachedUserRepository) CheckPassword(ctx context.Context, userID string, password string) (bool, error) { var count int64 err := r.GetDB(ctx).Model(&entities.User{}). Where("id = ? AND password = ?", userID, password). Count(&count).Error return count > 0, err } // ActivateUser 激活用户 func (r *ModernCachedUserRepository) ActivateUser(ctx context.Context, userID string) error { return r.GetDB(ctx).Model(&entities.User{}). Where("id = ?", userID). Update("active", true).Error } // DeactivateUser 停用用户 func (r *ModernCachedUserRepository) DeactivateUser(ctx context.Context, userID string) error { return r.GetDB(ctx).Model(&entities.User{}). Where("id = ?", userID). Update("active", false).Error } // UpdateLoginStats 更新登录统计 func (r *ModernCachedUserRepository) UpdateLoginStats(ctx context.Context, userID string) error { return r.GetDB(ctx).Model(&entities.User{}). Where("id = ?", userID). Updates(map[string]interface{}{ "login_count": gorm.Expr("login_count + 1"), "last_login_at": time.Now(), }).Error } // GetStats 获取用户统计信息 func (r *ModernCachedUserRepository) GetStats(ctx context.Context) (*repositories.UserStats, error) { var stats repositories.UserStats // 使用短期缓存获取统计信息 db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 5*time.Minute) // 总用户数 if err := db.Model(&entities.User{}).Count(&stats.TotalUsers).Error; err != nil { return nil, err } // 活跃用户数 if err := db.Model(&entities.User{}).Where("active = ?", true).Count(&stats.ActiveUsers).Error; err != nil { return nil, err } // 今日注册数 today := time.Now().Truncate(24 * time.Hour) if err := db.Model(&entities.User{}).Where("created_at >= ?", today).Count(&stats.TodayRegistrations).Error; err != nil { return nil, err } // 今日登录数 if err := db.Model(&entities.User{}).Where("last_login_at >= ?", today).Count(&stats.TodayLogins).Error; err != nil { return nil, err } return &stats, nil } // GetStatsByDateRange 获取指定日期范围的用户统计 func (r *ModernCachedUserRepository) GetStatsByDateRange(ctx context.Context, startDate, endDate string) (*repositories.UserStats, error) { var stats repositories.UserStats db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 10*time.Minute) // 指定时间范围内的注册数 if err := db.Model(&entities.User{}). Where("created_at >= ? AND created_at <= ?", startDate, endDate). Count(&stats.TodayRegistrations).Error; err != nil { return nil, err } // 指定时间范围内的登录数 if err := db.Model(&entities.User{}). Where("last_login_at >= ? AND last_login_at <= ?", startDate, endDate). Count(&stats.TodayLogins).Error; err != nil { return nil, err } return &stats, nil } // GetActiveUsers 获取活跃用户(使用短期缓存) func (r *ModernCachedUserRepository) GetActiveUsers(ctx context.Context) ([]entities.User, error) { var users []entities.User // 活跃用户查询使用短期缓存(5分钟) err := r.WithShortCache().FindWithCache(ctx, &users, 5*time.Minute, "active = ?", true) return users, err } // GetUsersByType 根据用户类型获取用户(使用中期缓存) func (r *ModernCachedUserRepository) GetUsersByType(ctx context.Context, userType string) ([]entities.User, error) { var users []entities.User // 用户类型查询使用中期缓存(30分钟) err := r.WithMediumCache().FindWithCache(ctx, &users, 30*time.Minute, "user_type = ?", userType) return users, err } // GetRecentUsers 获取最近注册用户(禁用缓存,实时数据) func (r *ModernCachedUserRepository) GetRecentUsers(ctx context.Context, limit int) ([]entities.User, error) { var users []entities.User // 最近用户查询禁用缓存,保证数据实时性 db := r.WithoutCache().GetDB(ctx) err := db.Order("created_at DESC").Limit(limit).Find(&users).Error return users, err } // GetPopularUsers 获取热门用户(使用长期缓存) func (r *ModernCachedUserRepository) GetPopularUsers(ctx context.Context, limit int) ([]entities.User, error) { var users []entities.User // 热门用户查询使用长期缓存(2小时) err := r.WithLongCache().GetDB(ctx). Order("login_count DESC"). Limit(limit). Find(&users).Error return users, err } // SearchUsers 搜索用户(智能缓存策略) func (r *ModernCachedUserRepository) SearchUsers(ctx context.Context, keyword string, limit int) ([]entities.User, error) { var users []entities.User // 搜索查询使用短期缓存,避免频繁的数据库查询 db := r.GetDB(ctx). Set("cache:enabled", true). Set("cache:ttl", 2*time.Minute). // 搜索结果缓存2分钟 Where("username LIKE ? OR phone LIKE ?", "%"+keyword+"%", "%"+keyword+"%"). Limit(limit) err := db.Find(&users).Error return users, err } // ================ 缓存管理方法 ================ // WarmupUserCache 预热用户缓存 func (r *ModernCachedUserRepository) WarmupUserCache(ctx context.Context) error { r.GetLogger().Info("开始预热用户缓存") // 定义预热查询 queries := []database.WarmupQuery{ { Name: "active_users", TTL: 30 * time.Minute, Dest: &[]entities.User{}, }, { Name: "user_types", TTL: 60 * time.Minute, Dest: &[]entities.User{}, }, { Name: "recent_users", TTL: 10 * time.Minute, Dest: &[]entities.User{}, }, } return r.WarmupCommonQueries(ctx, queries) } // RefreshUserCache 刷新用户缓存 func (r *ModernCachedUserRepository) RefreshUserCache(ctx context.Context) error { r.GetLogger().Info("刷新用户缓存") // 刷新用户相关的所有缓存 return r.RefreshCache(ctx, "users:*") } // GetUserCacheStats 获取用户缓存统计 func (r *ModernCachedUserRepository) GetUserCacheStats() map[string]interface{} { stats := r.GetCacheInfo() stats["specific_patterns"] = []string{ "gorm_cache:users:*", "user:id:*", "user:phone:*", } return stats } // ================ 使用示例 ================ // ExampleUsage 使用示例 func (r *ModernCachedUserRepository) ExampleUsage(ctx context.Context) { // 1. 基础查询(自动缓存) user, _ := r.GetByID(ctx, "user-123") r.GetLogger().Info("获取用户", zap.String("username", user.Username)) // 2. 手动控制缓存 // 使用短期缓存查询 var activeUsers []entities.User _ = r.WithShortCache().FindWithCache(ctx, &activeUsers, 5*time.Minute, "active = ?", true) r.GetLogger().Info("活跃用户数", zap.Int("count", len(activeUsers))) // 禁用缓存查询 var recentUsers []entities.User _ = r.WithoutCache().FindWhere(ctx, &recentUsers, "created_at > ?", time.Now().AddDate(0, 0, -7)) r.GetLogger().Info("最近用户数", zap.Int("count", len(recentUsers))) // 3. 智能缓存查询 options := interfaces.ListOptions{ Page: 1, PageSize: 20, Filters: map[string]interface{}{"active": true}, Sort: "created_at", Order: "desc", } users, _ := r.List(ctx, options) // 自动根据查询复杂度选择缓存策略 r.GetLogger().Info("用户列表", zap.Int("count", len(users))) // 4. 缓存预热 r.WarmupUserCache(ctx) }