package cache import ( "electricity_bill_calc/global" "fmt" "strings" "time" "github.com/rueian/rueidis" ) const ( TAG_ENTITY = "ENTITY" TAG_COUNT = "COUNT" TAG_SEARCH = "SEARCH" TAG_EXISTS = "CHECK" TAG_SESSION = "SESSION" TAG_RELATION = "RELATION" ) // 向Redis缓存中保存一个数据 // ! 如果需要长期保存一个数据,那么需要向expires传入0。 func Cache[T interface{}](key string, value *T, expires time.Duration) error { var err error if expires > 0 { setCmd := global.RedisConn.B().Set(). Key(key).Value(rueidis.JSON(value)). ExSeconds(int64(expires.Seconds())). Build() err = global.RedisConn.Do(global.Ctx, setCmd).Error() } else { setCmd := global.RedisConn.B().Set(). Key(key).Value(rueidis.JSON(value)). Build() err = global.RedisConn.Do(global.Ctx, setCmd).Error() } return err } // 从Redis缓存中获取一个数据 func Retreive[T interface{}](key string) (*T, error) { getCmd := global.RedisConn.B().Get().Key(key).Build() result := global.RedisConn.Do(global.Ctx, getCmd) if result.Error() != nil { if rueidis.IsRedisNil(result.Error()) { return nil, nil } else { return nil, result.Error() } } value := new(T) err := result.DecodeJSON(value) if err != nil { return nil, err } return value, nil } // 检查Redis缓存中是否存在指定键的记录 func Exists(key string) (bool, error) { existsCmd := global.RedisConn.B().Exists().Key(key).Build() result := global.RedisConn.Do(global.Ctx, existsCmd) if result.Error() != nil { return false, result.Error() } count, err := result.AsInt64() return count > 0, err } // 从Redis缓存中删除指定键 // ! 如果指定键已不存在,那么本函数一样会返回false func Delete(key string) (bool, error) { deleteCmd := global.RedisConn.B().Del().Key(key).Build() result := global.RedisConn.Do(global.Ctx, deleteCmd) if result.Error() != nil { return false, result.Error() } count, err := result.AsInt64() return count > 0, err } func dissembleScan(result rueidis.RedisResult) (int64, []string, error) { var ( err error cursor int64 keys = make([]string, 0) ) results, err := result.ToArray() if err != nil { return -1, keys, err } cursor, err = results[0].AsInt64() if err != nil { return -1, keys, err } keys, err = results[1].AsStrSlice() if err != nil { return -1, keys, err } return cursor, keys, err } // 从Redis缓存中批量删除符合pattern的键,这里的pattern直接使用Redis的pattern规则 func DeleteAll(pattern string) error { var ( err error cursor int64 keys = make([]string, 0) sKeys []string ) for { scanCmd := global.RedisConn.B().Scan().Cursor(cursor).Match(pattern).Count(20).Build() results := global.RedisConn.Do(global.Ctx, scanCmd) cursor, sKeys, err = dissembleScan(results) if err != nil { return err } keys = append(keys, sKeys...) if cursor == 0 { break } } delCmd := global.RedisConn.B().Del().Key(keys...).Build() err = global.RedisConn.Do(global.Ctx, delCmd).Error() return err } // 生成用于Redis存储的键 func CacheKey(category string, ids ...string) string { var b strings.Builder b.WriteString(category) for _, s := range ids { fmt.Fprintf(&b, ":%s", s) } return b.String() }