go-zero(十) 数据缓存和Redis使用

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中

相关推荐
晨岳2 小时前
CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
java·redis·mysql·nginx·centos·tomcat
执笔诉情殇〆2 小时前
前后端分离(java) 和 Nginx在服务器上的完整部署方案(redis、minio)
java·服务器·redis·nginx·minio
都叫我大帅哥4 小时前
🌟 Redis缓存与数据库数据一致性:一场数据世界的“三角恋”保卫战
redis
都叫我大帅哥4 小时前
Redis缓存雪崩:一场本可避免的"雪崩"灾难
redis
不像程序员的程序媛4 小时前
redis的一些疑问
java·redis·mybatis
考虑考虑4 小时前
Redis8新增特性
redis·后端·程序员
武子康5 小时前
大数据-38 Redis 分布式缓存 详细介绍 缓存、读写、旁路、穿透模式
大数据·redis·后端
AirMan6 小时前
深入浅出Redis:一文掌握Redis底层数据结构与实现原理
redis·后端·面试
千宇宙航6 小时前
闲庭信步使用图像验证平台加速FPGA的开发:第九课——图像插值的FPGA实现
图像处理·计算机视觉·缓存·fpga开发
全栈凯哥7 小时前
20.缓存问题与解决方案详解教程
java·spring boot·redis·后端·缓存