package redisclient import ( "context" "encoding/json" "fmt" "reflect" "time" ) // GetFromCacheOrDB 通用缓存获取方法 // cacheKey: 缓存键 // cacheTime: 缓存时间 // target: 目标结构体指针(需要传入指针) // dbFunc: 数据库查询函数,当缓存不存在时调用 func GetBytesFromCacheOrDB(cacheKey string, cacheTime time.Duration, target interface{}, dbFunc func() (interface{}, error)) error { // 1. 尝试从缓存获取 cacheDataStr, err := DefaultClient().Get(context.Background(), cacheKey).Result() if err == nil { if err := json.Unmarshal([]byte(cacheDataStr), target); err == nil { return nil } } // 2. 缓存未命中,从数据库获取 data, err := dbFunc() if err != nil { return err } // 3. 序列化数据并存入缓存(异步) go func() { cacheData, err := json.Marshal(data) if err != nil { return } if err := DefaultClient().Set(context.Background(), cacheKey, cacheData, cacheTime).Err(); err != nil { fmt.Println(fmt.Sprintf("failed to set cache for key %s: %v", cacheKey, err)) } }() // 4. 将数据赋值给target val := reflect.ValueOf(target) if val.Kind() != reflect.Ptr || val.IsNil() { return fmt.Errorf("target must be a non-nil pointer") } dataVal := reflect.ValueOf(data) if dataVal.Type().AssignableTo(val.Elem().Type()) { val.Elem().Set(dataVal) return nil } // 如果类型不匹配,尝试通过JSON转换 dataBytes, err := json.Marshal(data) if err != nil { return fmt.Errorf("failed to marshal data: %v", err) } return json.Unmarshal(dataBytes, target) } // 适用于保存json数据 func GetJsonDataFromCacheOrDB(cacheKey string, cacheTime time.Duration, target interface{}, dbFunc func() (interface{}, error)) error { // 1. 尝试从缓存获取 cacheDataStr, err := DefaultClient().Get(context.Background(), cacheKey).Result() if err == nil { if err := json.Unmarshal([]byte(cacheDataStr), target); err == nil { return nil } } // 2. 缓存未命中,从数据库获取 data, err := dbFunc() if err != nil { return err } // 3. 序列化数据并存入缓存(异步) go func() { cacheData, err := json.Marshal(data) if err != nil { return } if err := DefaultClient().Set(context.Background(), cacheKey, cacheData, cacheTime).Err(); err != nil { fmt.Println(fmt.Sprintf("failed to set cache for key %s: %v", cacheKey, err)) } }() // 4. 将数据赋值给target val := reflect.ValueOf(target) if val.Kind() != reflect.Ptr || val.IsNil() { return fmt.Errorf("target must be a non-nil pointer") } dataVal := reflect.ValueOf(data) if dataVal.Type().AssignableTo(val.Elem().Type()) { val.Elem().Set(dataVal) return nil } // 如果类型不匹配,尝试通过JSON转换 dataBytes, err := json.Marshal(data) if err != nil { return fmt.Errorf("failed to marshal data: %v", err) } return json.Unmarshal(dataBytes, target) }