go zero Redis使用和数据缓存
一、创建带有缓存的model
1.生成代码
我们还是使用之前的user
表,具体形式如下:
sql
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
;
现在我们可以通过goctl
来生成一带有缓存的model:
bash
goctl model mysql datasource -url="root:PXDN93VRKUm8TeE7@tcp(127.0.0.1:33069)/test_zero" -table="users" -dir ./model -c
-c
代表使用缓存
生成后我们把原来的model文件替换的掉,现在我们看下生成的代码:
go
// 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
多了一个c cache.CacheConf
cache参数
我们追踪下代码:
go
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 其实就是 Redis
2. 使用Cache
先在yaml
配置文件中,添加redis
的配置信息:
Cache:
- Host: "redisxxxxxx.redns.redis-cloud.com:16976"
Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y"
接着修改config.go
,在结构体中添加 cache:
go
type Config struct {
rest.RestConf
/*
....
*/
// 在结构体中增加cache
Cache cache.CacheConf
}
最后在servicecontext.go
中,修改NewUserModel
的参数:
go
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. 测试
现在我们运行项目测试一下:
我们登录账号后,可以看到redis里面多了一个信息:
二、 使用redis
刚刚我们介绍了cache,也知道了cache就是redis,现在来正式介绍下redis.
还是一样我们首先要配置redis
1. 配置redis
先在yaml
配置文件中,添加redis
的配置信息:
RedisConfig:
- Host: "redisxxxxxx.redns.redis-cloud.com:16976"
Pass: "lb8ZWuQwJENyzRiHUFjNnGJG0fgnKx5y
如果资源比较有限可以把redis 和cache用同一个配置,如果资源比较富裕可以分开使用。
接着修改config.go
,在结构体中添加 redis配置:
go
type Config struct {
rest.RestConf
/*
....
*/
// 在结构体中增加redis配置
RedisConfig redis.RedisConf
}
最后在servicecontext.go
中,添加redis:
go
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
修改服务端代码,在登录实现token存储到redis中:
go
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, "数据库连接失败")
}
//从配置文件中获取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错误")
}
//查询username判断是否有数据
if user != nil {
//如果有数据,密码是否和数据库匹配
if in.Password == user.Password {
return &pb.LoginResp{
Token: "Bearer " + token, //开头添加Bearer
}, nil
} else {
return nil, errors.New(5, "密码错误")
}
} else {
return nil, errors.New(6, "用户未注册")
}
}
redis 的设置方法有几种,具体的可以看代码,我这里使用的是SetexCtx
3. 运行项目测试
可以看到token 成功的存储到了redis中