Decorative implemented cache package

Redis achieve cache decorator, routing function

func GetTopicDetail(context *gin.Context)  {
    tid:=context.Param("topic_id")
    topics:=Topics{}
    DBHelper.Find(&topics,tid)//从数据库取
    context.Set("dbResult",topics) //这里dbResult暂时写死,应该从配置文件中读取,每一次从数据库查询到的值都会写到
}

Bind handler to route

v1.GET("/:topic_id", CacheDecorator(GetTopicDetail,"topic_id","topic_%s",Topic{}))

Achieve decorator

func CacheDecorator(h gin.HandlerFunc,param string,redKeyPattern string,empty interface{}) gin.HandlerFunc {
    return func(context *gin.Context) {
        //redis判断
        getID:=context.Param(param) //得到ID值
        redisKey:=fmt.Sprintf(redKeyPattern,getID)
        conn:=RedisDefaultPool.Get()
        defer conn.Close()
        ret,err:=redis.Bytes(conn.Do("get",redisKey))
        if err!=nil { //缓存里没有
            h(context)//执行目标方法,这里执行了GetTopicDetail方法,把mysql查询到的结果放到了context中
            dbResult,exists:=context.Get("dbResult") //拿出context中保存的查询结果
            if !exists{
                dbResult=empty //如果缓存里没有则初始化一条空数据
            }
            retData,_:=json.Marshal(dbResult) //序列化查询结果
            conn.Do("setex",redisKey,20,retData) //存入redis
            context.JSON(200,dbResult)
            log.Println("从数据库读取")
        }else{//缓存有 ,直接抛出
             log.Println("从 redis读取")
             json.Unmarshal(ret,&empty)
             context.JSON(200,empty)
        }

    }
}




Guess you like

Origin www.cnblogs.com/hualou/p/12071043.html