Git Product home page Git Product logo

gorm-cache's Introduction

package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"github.com/liyuan1125/gorm-cache"
	redis2 "github.com/liyuan1125/gorm-cache/store/redis"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"os"
	"time"
)

var (
	db *gorm.DB

	redisClient *redis.Client

	cachePlugin *cache.Cache
)

func newDb() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local"
	var err error

	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	redisClient = redis.NewClient(&redis.Options{Addr: ":6379"})

	cacheConfig := &cache.Config{
		Store:      redis2.NewWithDb(redisClient), // OR redis2.New(&redis.Options{Addr:"6379"})
		Serializer: &cache.DefaultJSONSerializer{},
	}

	cachePlugin = cache.New(cacheConfig)

	if err = db.Use(cachePlugin); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
}

func basic() {
	var username string
	ctx := context.Background()
	ctx = cache.NewExpiration(ctx, time.Hour)

	db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("username", &username)
	fmt.Println(username)
	// output gorm
}

func customKey() {
	var nickname string
	ctx := context.Background()
	ctx = cache.NewExpiration(ctx, time.Hour)
	ctx = cache.NewKey(ctx, "nickname")

	db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname)

	fmt.Println(nickname)
	// output gormwithmysql
}

func useTag() {
	var nickname string
	ctx := context.Background()
	ctx = cache.NewExpiration(ctx, time.Hour)
	ctx = cache.NewTag(ctx, "users")

	db.Table("users").WithContext(ctx).Where("id = 1").Limit(1).Pluck("nickname", &nickname)

	fmt.Println(nickname)
	// output gormwithmysql
}

func main() {
	newDb()
	basic()
	customKey()
	useTag()

	ctx := context.Background()
	fmt.Println(redisClient.Keys(ctx, "*").Val())

	fmt.Println(cachePlugin.RemoveFromTag(ctx, "users"))
}

gorm-cache's People

Contributors

liyuan1125 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

gorm-cache's Issues

缓存key有问题

` // 调用 Gorm的方法生产SQL
callbacks.BuildQuerySQL(tx)

// 是否有自定义key
if key, hasKey = FromKey(ctx); !hasKey {
	key = p.prefix + generateKey(tx.Statement.SQL.String())
}`

未定义key的时候,使用tx.Statement.SQL.String()计算出key,但是callbacks.BuildQuerySQL(tx)处理后,sql语句的值还未放进去。比如,SELECT * FROM enum WHERE type_id = ?,是这样的状态。这样就导致外部传的不同的type_id,但是key计算的却是同一个。太坑了。

新版本的思路

新版本的打算解析sql的语句,使用tableName+where+group+order+limit 等其他子句,生成一个key
例如

SELECT * FROM users WHERE username = 'gorm' order by id DESC limit 1;

以上sql生成的缓存 hashKey 大概为

users.username.gorm.order.id.desc.limit.1

然后使用go生成一个hash值,再缓存的redis内

由于gorm内获取不到where 等字句,所以想使用 vitess

如果不使用子句,例如order by group的话,可以在更新与删除时将缓存删除
例如users.username.gorm 这在更新的时候

UPDATE users SET avatar = '1.png' WHERE username = 'gorm';

或者删除数据的时候

DELETE FROM users WHERE username = 'gorm';

以上两个sql都可以生成users.username.gorm(tableName+where)

这时候可以删除缓存,但是这面临到一个问题,就是数据可能不对
例如

id username avatar
1 gorm 1.png
2 gorm 2.png
SELECT * FROM `users` WHERE username = 'gorm' ORDER BY id DESC limit 1;

SELECT * FROM `users` WHERE username = 'gorm' ORDER BY id ASC limit 1;

SELECT * FROM `users` WHERE username = 'gorm' ORDER BY id ASC;

以上三个语句查询到的数据有可能不是一样的,但是缓存的数据就会有问题,

所以目前还在考虑用哪个方案

一点点建议

兄弟,我没有用你的库,但是我仔细看了一下源码,有很多参考学习意义。

  1. 我看源码中只代理了Query,Update和Delete都没有做处理。
  2. 缓存使用超时处理的,但是数据更新了,缓存没过期的时候得到的还是旧的数据。

我看go-zero的缓存处理,query raw的时候创建缓存,在update的时候更新缓存,remove的时候就清除缓存,query raws的时候不进行缓存。

库中有很多可以优化的地方。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.