// 序列化 存储
func (r *RedisClient) SetStructValue(key string, value interface{}, expiration time.Duration) error {
codec := &cache.Codec{
Redis: r.Client,
Marshal: func(v interface{}) ([]byte, error) {
return msgpack.Marshal(v)
},
Unmarshal: func(b []byte, v interface{}) error {
return msgpack.Unmarshal(b, v)
},
}
if err := codec.Set(&cache.Item{
Key: key,
Object: value,
Expiration: expiration,
}); err != nil {
logrus.Errorf("redis cache error, %s, %v, %v", key, value, err)
return err
}
return nil
}
// 序列化 读取
func (r *RedisClient) GetStructValue(key string, value interface{}) error {
codec := &cache.Codec{
Redis: r.Client,
Marshal: func(v interface{}) ([]byte, error) {
return msgpack.Marshal(v)
},
Unmarshal: func(b []byte, v interface{}) error {
return msgpack.Unmarshal(b, v)
},
}
if err := codec.Get(key, value); err != nil {
logrus.Warnf("get redis cache error, %s, %v", key, err)
return err
}
return nil
}
----------------------------
// 将 struct 用 redis hash 结构保存
// 注意:此方法暂时只支持简单结构,即对象内部key 的类型需要为基本类型
func (r *RedisClient) HashMapSet(key string, v interface{}) error {
b, err := json.Marshal(v)
if err != nil {
return err
}
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
return err
}
data := f.(map[string]interface{})
return r.HMSet(key, data).Err()
}
// 将 redis hash 结构数据转化为 struct
// 注意:此方法暂时只支持简单结构,即对象内部key 的类型需要为基本类型
func (r *RedisClient) HashMapGet(key string, v interface{}) error {
mapValue := r.HGetAll(key).Val()
decoder, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
WeaklyTypedInput: true,
Result: v,
})
if err := decoder.Decode(mapValue); err != nil {
return err
}
return nil
}
//对上面方法的完善:
//struct映射
func (s *commentRedisStore) CommentMapToStruct(commentInfo *model.CommentInfo, mapValue map[string]string) error {
if len(mapValue) == 0 { //因为当len(mapValue) == 0时,commentInfo也有,只不过是字段为空
return errors.New("len(mapValue) == 0")
}
decoder, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
WeaklyTypedInput: true,
Result: commentInfo,
})
_ = decoder.Decode(mapValue)
//重填时间
if mapValue["createdAt"] != "" {
timeStr := mapValue["createdAt"]
commentInfo.CreatedAt, _ = time.Parse("2006-01-02T15:04:05Z07:00", timeStr)
}
if mapValue["updatedAt"] != "" {
timeStr := mapValue["updatedAt"]
commentInfo.UpdatedAt, _ = time.Parse("2006-01-02T15:04:05Z07:00", timeStr)
}
if mapValue["deletedAt"] != "" {
timeStr := mapValue["deletedAt"]
deletedAt, _ := time.Parse("2006-01-02T15:04:05Z07:00", timeStr)
commentInfo.DeletedAt = &deletedAt
} else {
commentInfo.DeletedAt = nil
}
return nil
}
go-redis/cache:https://godoc.org/github.com/go-redis/cache
cache是redis存储前的数据体,提供组装数据功能,.set方法可以直接存储redis
mitchellh/mapstructure: https://godoc.org/github.com/mitchellh/mapstructure
包mapstructure提供了将任意map [string] interface {}转换为本地Go结构的功能。Go结构可以是任意复杂的,包含切片,其他结构等,并且解码器将正确解码嵌套映射,依此类推,成为本地Go结构中的适当结构。