feat(cache):实验性增加缓存操作函数。
This commit is contained in:
parent
4aa7221158
commit
4025965e98
8
cache/abstract.go
vendored
8
cache/abstract.go
vendored
@ -10,6 +10,14 @@ import (
|
|||||||
"github.com/vmihailenco/msgpack/v5"
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TAG_ENTITY = "ENTITY"
|
||||||
|
TAG_COUNT = "COUNT"
|
||||||
|
TAG_SEARCH = "SEARCH"
|
||||||
|
TAG_EXISTS = "CHECK"
|
||||||
|
TAG_SESSION = "SESSION"
|
||||||
|
)
|
||||||
|
|
||||||
// 向Redis缓存中保存一个数据
|
// 向Redis缓存中保存一个数据
|
||||||
// ! 如果需要长期保存一个数据,那么需要向expires传入0。
|
// ! 如果需要长期保存一个数据,那么需要向expires传入0。
|
||||||
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
func Cache[T interface{}](key string, value *T, expires time.Duration) error {
|
||||||
|
52
cache/count.go
vendored
Normal file
52
cache/count.go
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/global"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assembleCountKey(entityName string) string {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, strings.ToUpper(entityName))
|
||||||
|
return CacheKey(TAG_COUNT, keys...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assembleCountIdentification(additional ...string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
for _, s := range additional {
|
||||||
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向缓存中缓存模型名称明确的包含指定条件的实体记录数量
|
||||||
|
func CacheCount(entityName string, count int64, conditions ...string) error {
|
||||||
|
countKey := assembleCountKey(entityName)
|
||||||
|
identification := assembleCountIdentification(conditions...)
|
||||||
|
result := global.RedisConn.HSet(global.Ctx, countKey, map[string]interface{}{identification: count})
|
||||||
|
return result.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中获取模型名称明确的,包含指定条件的实体记录数量
|
||||||
|
func RetreiveCount(entityName string, condtions ...string) (int64, error) {
|
||||||
|
countKey := assembleCountKey(entityName)
|
||||||
|
identification := assembleCountIdentification(condtions...)
|
||||||
|
result := global.RedisConn.HGet(global.Ctx, countKey, identification)
|
||||||
|
if result.Err() != nil {
|
||||||
|
return -1, result.Err()
|
||||||
|
}
|
||||||
|
count, err := strconv.ParseInt(result.Val(), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除指定模型名称的数量缓存
|
||||||
|
func AbolishCountEntity(entityName string) error {
|
||||||
|
countKey := assembleCountKey(entityName)
|
||||||
|
result := global.RedisConn.Del(global.Ctx, countKey)
|
||||||
|
return result.Err()
|
||||||
|
}
|
61
cache/entity.go
vendored
Normal file
61
cache/entity.go
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/global"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assembleEntityKey(entityName, id string) string {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, TAG_ENTITY)
|
||||||
|
keys = append(keys, strings.ToUpper(entityName), id)
|
||||||
|
var b strings.Builder
|
||||||
|
for _, s := range keys {
|
||||||
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存模型名称明确的,使用ID进行检索的实体内容。
|
||||||
|
func CacheEntity[T any](instance T, entityName, id string) error {
|
||||||
|
entityKey := assembleEntityKey(entityName, id)
|
||||||
|
err := Cache(entityKey, &instance, 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中取出模型名称明确的,使用ID进行检索的实体内容。
|
||||||
|
func RetreiveEntity[T any](entityName, id string) (T, error) {
|
||||||
|
entityKey := assembleEntityKey(entityName, id)
|
||||||
|
instance, err := Retreive[T](entityKey)
|
||||||
|
return *instance, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 精确的从缓存中删除指定模型名称、指定ID的实体内容。
|
||||||
|
func AbolishSpecificEntity(entityName, id string) (bool, error) {
|
||||||
|
entityKey := assembleEntityKey(entityName, id)
|
||||||
|
return Delete(entityKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中删除指定模型名称的所有内容。
|
||||||
|
func AbolishEntity(entityName string) error {
|
||||||
|
var (
|
||||||
|
cursor uint64
|
||||||
|
keys = make([]string, 0)
|
||||||
|
)
|
||||||
|
pattern := fmt.Sprintf("%s:%s:*", TAG_ENTITY, strings.ToUpper(entityName))
|
||||||
|
for {
|
||||||
|
k, cursor, err := global.RedisConn.Scan(global.Ctx, cursor, pattern, 20).Result()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
keys = append(keys, k...)
|
||||||
|
if cursor == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipeline := global.RedisConn.Pipeline()
|
||||||
|
pipeline.Del(global.Ctx, keys...)
|
||||||
|
_, err := pipeline.Exec(global.Ctx)
|
||||||
|
return err
|
||||||
|
}
|
70
cache/exists.go
vendored
Normal file
70
cache/exists.go
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/tools"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assembleExistsKey(entityName string) string {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, strings.ToUpper(entityName))
|
||||||
|
return CacheKey(TAG_EXISTS, keys...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assembleExistsIdentification(id string, additional ...string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.WriteString(id)
|
||||||
|
for _, s := range additional {
|
||||||
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存模型名称明确的、包含指定ID以及一些附加条件的记录
|
||||||
|
func CacheExists(entityName, id string, conditions ...string) error {
|
||||||
|
existskey := assembleExistsKey(entityName)
|
||||||
|
identification := assembleExistsIdentification(id, conditions...)
|
||||||
|
result := global.RedisConn.SAdd(global.Ctx, existskey, identification)
|
||||||
|
return result.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中获取模型名称明确、包含指定ID以及一些附加条件的实体是否存在的标记,函数在返回false时不保证数据库中相关记录也不存在
|
||||||
|
func CheckExists(entityName, id string, condtions ...string) (bool, error) {
|
||||||
|
existsKey := assembleExistsKey(entityName)
|
||||||
|
identification := assembleExistsIdentification(id, condtions...)
|
||||||
|
result := global.RedisConn.SIsMember(global.Ctx, existsKey, identification)
|
||||||
|
return result.Val(), result.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中删除模型名称明确、包含指定ID的全部实体存在标记
|
||||||
|
func AbolishExists(entityName, id string) error {
|
||||||
|
existsKey := assembleExistsKey(entityName)
|
||||||
|
pattern := fmt.Sprintf("%s*", id)
|
||||||
|
var (
|
||||||
|
cursor uint64
|
||||||
|
elems = make([]string, 0)
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
k, cursor, err := global.RedisConn.SScan(global.Ctx, existsKey, cursor, pattern, 20).Result()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
elems = append(elems, k...)
|
||||||
|
if cursor == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipeline := global.RedisConn.Pipeline()
|
||||||
|
pipeline.SRem(global.Ctx, existsKey, tools.ConvertSliceToInterfaceSlice(elems)...)
|
||||||
|
_, err := pipeline.Exec(global.Ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中删除指定模型名称的全部存在标记
|
||||||
|
func AbolishExistsEntity(entityName string) error {
|
||||||
|
existskey := assembleExistsKey(entityName)
|
||||||
|
result := global.RedisConn.Del(global.Ctx, existskey)
|
||||||
|
return result.Err()
|
||||||
|
}
|
56
cache/search.go
vendored
Normal file
56
cache/search.go
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/global"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assembleSearchKey(entityName string, additional ...string) string {
|
||||||
|
var keys = make([]string, 0)
|
||||||
|
keys = append(keys, TAG_SEARCH)
|
||||||
|
keys = append(keys, strings.ToUpper(entityName))
|
||||||
|
keys = append(keys, additional...)
|
||||||
|
var b strings.Builder
|
||||||
|
for _, s := range keys {
|
||||||
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||||
|
func CacheSearch[T any](instance T, entityName string, conditions ...string) error {
|
||||||
|
searchKey := assembleSearchKey(entityName, conditions...)
|
||||||
|
err := Cache(searchKey, &instance, 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中取得模型名称明确的,使用或者包含非ID检索条件的实体内容。
|
||||||
|
func RetreiveSearch[T any](entityName string, conditions ...string) (T, error) {
|
||||||
|
searchKey := assembleSearchKey(entityName, conditions...)
|
||||||
|
instance, err := Retreive[T](searchKey)
|
||||||
|
return *instance, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从缓存中删除全部指定模型名称的实体内容。
|
||||||
|
func AbolishSearch(entityName string) error {
|
||||||
|
var (
|
||||||
|
cursor uint64
|
||||||
|
keys = make([]string, 0)
|
||||||
|
)
|
||||||
|
pattern := fmt.Sprintf("%s:%s:*", TAG_SEARCH, strings.ToUpper(entityName))
|
||||||
|
for {
|
||||||
|
k, cursor, err := global.RedisConn.Scan(global.Ctx, cursor, pattern, 20).Result()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
keys = append(keys, k...)
|
||||||
|
if cursor == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipeline := global.RedisConn.Pipeline()
|
||||||
|
pipeline.Del(global.Ctx, keys...)
|
||||||
|
_, err := pipeline.Exec(global.Ctx)
|
||||||
|
return err
|
||||||
|
}
|
2
cache/session.go
vendored
2
cache/session.go
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func SessionKey(keys ...string) string {
|
func SessionKey(keys ...string) string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
b.WriteString("session")
|
b.WriteString(TAG_SESSION)
|
||||||
for _, s := range keys {
|
for _, s := range keys {
|
||||||
fmt.Fprintf(&b, ":%s", s)
|
fmt.Fprintf(&b, ":%s", s)
|
||||||
}
|
}
|
||||||
|
@ -30,3 +30,11 @@ func ConvertStructToMap[T any](origin T) map[string]interface{} {
|
|||||||
json.Unmarshal(incr, &dest)
|
json.Unmarshal(incr, &dest)
|
||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertSliceToInterfaceSlice[T any](origin []T) []interface{} {
|
||||||
|
dest := make([]interface{}, len(origin))
|
||||||
|
for i, e := range origin {
|
||||||
|
dest[i] = e
|
||||||
|
}
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user