Describe the feature

在一些特殊的查询下 可以接受一段时间内,直接获取缓存数据(redis),这个时候可以来直接调用官方提供的方法来实现, 虽然开发者也可以去实现,但是我感觉写在官方库内会更好, 场景1比如需要统计一些没有实时要求数据时,我们就可以通过缓存结果来实现快速反馈,和性能提升

Motivation

Related Issues

Comment From: a631807682

You can do it yourself using singleflight or sponsor gorm author to create a new project. It won't do the specific business development for you.

Comment From: pnck

你怎么会有「写在官方库内更好」的想法,不如看看 pg redis fdw

Comment From: liyuan1125


func generateKey(v string) uint64 {
    hash := fnv.New64a()
    _, _ = hash.Write([]byte(v))

    return hash.Sum64()
}


func QueryCache(tx *gorm.DB) {
    ctx := tx.Statement.Context

    callbacks.BuildQuerySQL(tx)

    key := strconv.FormatUint(generateKey(tx.Statement.SQL.String()), 36)
    ttl := ctx.Value("cache")
    if ttl == nil {
        callbacks.Query(tx)
        return
    }

    tx.Logger.Warn(ctx, "use cache")

    values, err := RedisDB().Get(ctx, key).Bytes()
    if err != nil {
        callbacks.Query(tx)
        if tx.Error != nil {
            return
        }

        if values, err = json.Marshal(tx.Statement.Dest); err != nil {
            tx.Logger.Error(ctx, err.Error())
            return
        }

        expiration, ok := ttl.(time.Duration)
        fmt.Println(ok)
        if !ok {
            expiration = time.Hour
        }

        RedisDB().Set(tx.Statement.Context, key, values, expiration)
        return
    }

    if err = json.Unmarshal(values, &tx.Statement.Dest); err != nil {
        tx.Logger.Error(ctx, err.Error())
    }
}


ctx = context.WithValue(ctx, "cache", time.Minute*10)
user := &model.User{}
db.WithContext(ctx).Model(&model.User{}).Limit(1).Find(user)

Comment From: li-jin-gou

gorm 支持 plugin,如果有比较好的 idea 可以通过插件扩展缓存能力的,欢迎PR哈 https://gorm.cn/zh_CN/docs/write_plugins.html

Comment From: liyuan1125

gorm 支持 plugin,如果有比较好的 idea 可以通过插件扩展缓存能力的,欢迎PR哈 https://gorm.cn/zh_CN/docs/write_plugins.html

这里做了一个。不知道是否能收录呢? https://github.com/liyuan1125/gorm-cache