gorm通过callback实时更新缓存数据

在一个我们需要更新缓存数据的场景下时,有许多选择的余地,django中很多时候使用celery定时任务,但是单用celery定时任务也许无法保证数据的实时更新。

比如django框架中包含了很多signal,单独使用signal的话并没有什么性能上的优势,通过结合一些类似celery异步任务使用真的很好用,基本可以做到数据的实时更新。

在golang的gorm框架中也提供了callback方法,具体可以参考官方文档https://gorm.io/docs/hooks.html,配合go天然的并发优势简直爽到不行0.0

下面以更新redis缓存为例

package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/vmihailenco/msgpack"
	"log"
	"strconv"
	"sync"
)

type user struct {
	Id uint `json:"id" gorm:"primary_key"`
	Name string `json:"name" gorm:"not null"`
}

var wg sync.WaitGroup

func redisCon() *redis.Client{
	conn := redis.NewClient(&redis.Options{
		Addr:     "192.168.50.15:6379",
		Password: "",
		DB:       1,
	})
	err := conn.Ping().Err()
	if err != nil {
		log.Fatal("连接redis失败")
	}
	return conn
}

// 刷新
func flashInfo(u *user)  {
	defer wg.Done()
	conn := redisCon()
	defer conn.Close()
	// 序列化
	info, _ := msgpack.Marshal(u)
	// 存入hash
	idStr := strconv.Itoa(int(u.Id))
	err := conn.HSet("user_info", idStr, info).Err()
	if err != nil {
		fmt.Printf("更新缓存出错了,err:%s",err.Error())
		return
	}
	fmt.Println("更新缓存完成了")
}

// 获取信息
func getInfo(key,field string){
	conn := redisCon()
	defer conn.Close()
	val, _ := conn.HGet(key, field).Bytes()
	var u user
	err := msgpack.Unmarshal(val,&u)
	if err != nil {
		fmt.Printf("获取缓存数据出错了,err:%s\n",err.Error())
		return
	}
	fmt.Printf("用户名已被更新为:%s\n",u.Name)
}


func beforeUpdate(scope *gorm.Scope)  {
	fmt.Println("我要准备更新user了")
}

func afterUpdate(scope *gorm.Scope) {
	fmt.Println("更新user成功了,我要准备更新缓存了")
	value := scope.IndirectValue().Interface()
	// 转换对应结构体
	u := value.(user)
	fmt.Println("我开始更新缓存了")
	// 更新缓存
	wg.Add(1)
	go flashInfo(&u)
	wg.Wait()


	idStr := strconv.Itoa(int(u.Id))
	getInfo("user_info",idStr)
}

func (u *user) updateUser(db *gorm.DB) error {
	db.Model(u).Update("name",u.Name).Callback().Update().After("gorm:beforeUpdate").Before("gorm:beforeUpdate")
	return nil
}

func main() {
	db, err := gorm.Open("mysql", "edu:123456@tcp(192.168.50.15:33306)/gormtest?charset=utf8&parseTime=True")
	if err != nil {
		fmt.Println(err)
	}
	defer db.Close()
	u := &user{
		Id: 1,
		Name: "fff",
	}
	// 注册方法
	db.Callback().Update().Register("gorm:beforeUpdate", beforeUpdate)
	db.Callback().Update().Register("gorm:afterUpdate", afterUpdate)
	u.updateUser(db)
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值