beego cache 对 redis 的封装感觉不好用啊,求指教

楼主新手上路,提出一些疑问

没有不敬的意思,就是想问问,想请老司机指教一下我该怎么办

    //Set 的时候,还看不出有什么问题
    err := cache.BM.Put("foo", "bar", 10 * time.Second)
    if err != nil {
        fmt.Println("set value fail", err)
    }

    //但是 Get 的时候,则有很多问题
    result := cache.BM.Get("foo")
    //beego cache 的 Get 方法里面,对 error 做了处理,如果取失败了就返回 nil ,成功则返回一个接口类型

    if result == nil {
        fmt.Println("get value fail")
    } else {
        value, err := redis.String(result, nil)
        //返回的接口类型一般要通过 redigo 的各种方法转换成要用的类型
        //这里就要手动传一个 nil , 因为 redis.String 需要两个参数
        //beego 的 cache 在这里是不是过度封装了?
        if err != nil {
            //error handle
        } else {
            fmt.Println("get value is ", value)
        }
    }

    //用 redigo 原始的方法写,则简单多了
    c := redisService.Pool.Get()
    defer c.Close()

    v, err := redis.String(c.Do("GET", "name"))
    if err != nil {
        //error handle
    }else{
        fmt.Println("get value is ", v)
    }

还有常常用到 redis 的 incr 方法

    //这个是 beego cache redis 的封装
    //rc.do("INCRBY", key, 1) 返回的增加后的值被忽略了,也不能设置增加的步长
    //业务中常常要获取增加后的值的,比如做一个简单的发号器的时候
    func (rc *Cache) Incr(key string) error {
        _, err := redis.Bool(rc.do("INCRBY", key, 1))
        return err
    }

而且 beego cache 中封装的连接池 ,外面没办法取到(非导出的) 这样如果要用上面的功能,是否就需要自己搞个连接池?

已邀请:

fanyang - 改变未来的技术

赞同来自:

result := cache.BM.Get("foo")
if result == nil {
    fmt.Println("get value fail")
}else{
     //不管值是json、数值、字符都返回[]unit8
     fmt.Println("get value is ", string(result.([]uint8)) )   
}
value, err := redis.String(cache.BM.Get("foo"), nil)
 if err != nil {
    //return err: "redigo: nil returned."
 } else {
     fmt.Println("get value is ", value)
}

INCRBY累加1,想要获取增加后的值就用Get获取,链接池没必要暴露,在内部操作就可以,如果还是觉得不方便可以修改beego 封装的redis

fanyang - 改变未来的技术

赞同来自:

我自己封装了对redis的操作,没有设置TTL的 -redis --hash.go --redis.go --set.go --string.go

type client struct {
    pool *redis.Pool // redis connection pool
}

func (c *client) do(commandName string, args ...interface{}) (reply interface{}, err error) {
    rc := c.pool.Get()
    defer rc.Close()
    return rc.Do(commandName, args...)
}

//Set 设置字符串值
func (c *client) Set(key string, value interface{}) error {
    data, err := json.Marshal(value)
    if err != nil {
        //插入基本类型
        _, err = c.do("SET", key, value)
    } else {
        //插入对象或数组
        _, err = c.do("SET", key, data)
    }
    return err
}

//Get 获取字符串值
func (c *client) Get(key string) ([]byte, error) {
    return redis.Bytes(c.do("GET", key))
}

//HGetAll 获取哈希表所有的域和值
func (c *client) HGetAll(key string) ([]byte, error) {
    object, err := redis.InterfaceMap(c.do("HGETALL", key))
    if err != nil {
        return nil, err
    }
    if len(object) == 0 {
        return nil, errors.New(key + " does not exist in the hash table")
    }
    return json.Marshal(object)
}

bfcaicai - 向往niubility...

赞同来自:

用beego封装了一个单独的处理缓存的服务 引入redis和file两种引擎,redis自己写了TTL方法,目前多个应用使用下来感觉还是比较好用的!

lide

赞同来自:

简单封装了下beego的cache,增加了hash支持,不知是不是有必要 https://github.com/lidedongsn/cache.git

要回复问题请先登录注册