go zero Redis使用和數(shù)據(jù)緩存
一、創(chuàng)建帶有緩存的model
1.生成代碼
我們還是使用之前的user表,具體形式如下:
CREATE TABLE `users` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
`password` VARCHAR(255) NOT NULL COLLATE 'utf8_general_ci',
`created_at` TIMESTAMP NULL DEFAULT (CURRENT_TIMESTAMP),
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `username` (`username`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
現(xiàn)在我們可以通過goctl來生成一帶有緩存的model:
goctl model mysql datasource -url="root:PXDN93VRKUm8TeE7@tcp(127.0.0.1:33069)/test_zero" -table="users" -dir ./model -c
-c 代表使用緩存
生成后我們把原來的model文件替換的掉,現(xiàn)在我們看下生成的代碼:
// NewUsersModel returns a model for the database table.
func NewUsersModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UsersModel {
return &customUsersModel{
defaultUsersModel: newUsersModel(conn, c, opts...),
}
}
NewUsersModel 多了一個(gè)c cache.CacheConf cache參數(shù)
我們追蹤下代碼:
type CacheConf = ClusterConf
接著追蹤:
type (
// A ClusterConf is the config of a redis cluster that used as cache.
ClusterConf []NodeConf
// A NodeConf is the config of a redis node that used as cache.
NodeConf struct {
redis.RedisConf
Weight int `json:",default=100"`
}
)
通過上面兩段代碼可以看到 cache 其實(shí)就是 Redis
2. 使用Cache
先在yaml配置文件中,添加redis的配置信息:
Cache:
- Host: "redisxxxxxx.redns.redis-cloud.com:16976"
Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y"
接著修改config.go,在結(jié)構(gòu)體中添加 cache:
type Config struct {
rest.RestConf
/*
....
*/
// 在結(jié)構(gòu)體中增加cache
Cache cache.CacheConf
}
最后在servicecontext.go 中,修改NewUserModel的參數(shù):
type ServiceContext struct {
Config config.Config
/*
....
*/
UserModel model.UserModel
}
func NewServiceContext(c config.Config) *ServiceContext {
//mysql := NewMysql(c.MysqlDB.DbSource)
return &ServiceContext{
Config: c,
/*
....
*/
UserModel: model.NewUserModel(sqlx.NewMysql(c.MysqlDB.DbSource), c.Cache),
}
}
3. 測(cè)試
現(xiàn)在我們運(yùn)行項(xiàng)目測(cè)試一下:
我們登錄賬號(hào)后,可以看到redis里面多了一個(gè)信息:

image.png
二、 使用redis
剛剛我們介紹了cache,也知道了cache就是redis,現(xiàn)在來正式介紹下redis.
還是一樣我們首先要配置redis
1. 配置redis
先在yaml配置文件中,添加redis的配置信息:
RedisConfig:
- Host: "redisxxxxxx.redns.redis-cloud.com:16976"
Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y
如果資源比較有限可以把redis 和cache用同一個(gè)配置,如果資源比較富裕可以分開使用。
接著修改config.go,在結(jié)構(gòu)體中添加 redis配置:
type Config struct {
rest.RestConf
/*
....
*/
// 在結(jié)構(gòu)體中增加redis配置
RedisConfig redis.RedisConf
}
最后在servicecontext.go 中,添加redis:
type ServiceContext struct {
Config config.Config
/*
....
*/
Redis *redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
//mysql := NewMysql(c.MysqlDB.DbSource)
return &ServiceContext{
Config: c,
/*
....
*/
//使用MustNewRedis 鏈接redis
Redis: redis.MustNewRedis(c.RedisConfig),
}
}
2. 使用redis 保存token
修改服務(wù)端代碼,在登錄實(shí)現(xiàn)token存儲(chǔ)到redis中:
func (l *LoginLogic) Login(in *pb.LoginReq) (*pb.LoginResp, error) {
// todo: add your logic here and delete this line
userModel := l.svcCtx.UserModel
user, err := userModel.FindOneByUsername(l.ctx, in.Username)
if err != nil && err != model.ErrNotFound {
return nil, errors.New(0, "數(shù)據(jù)庫(kù)連接失敗")
}
//從配置文件中獲取secret 、secret
secret := l.svcCtx.Config.JwtAuth.AccessSecret
expire := l.svcCtx.Config.JwtAuth.AccessExpire
//生成jwt token
token, err := getJwtToken(secret, time.Now().Unix(), expire, in.Username)
if err != nil {
return nil, errors.New(4, "token生成失敗")
}
// 登錄成功后將用戶信息寫入 Redis
err = l.svcCtx.Redis.SetexCtx(l.ctx, fmt.Sprintf("token:%s", token), in.Username, int(expire))
if err != nil {
return nil, errors.New(66, "redis錯(cuò)誤")
}
//查詢username判斷是否有數(shù)據(jù)
if user != nil {
//如果有數(shù)據(jù),密碼是否和數(shù)據(jù)庫(kù)匹配
if in.Password == user.Password {
return &pb.LoginResp{
Token: "Bearer " + token, //開頭添加Bearer
}, nil
} else {
return nil, errors.New(5, "密碼錯(cuò)誤")
}
} else {
return nil, errors.New(6, "用戶未注冊(cè)")
}
}
redis 的設(shè)置方法有幾種,具體的可以看代碼,我這里使用的是SetexCtx
3. 運(yùn)行項(xiàng)目測(cè)試
可以看到token 成功的存儲(chǔ)到了redis中

image.png