油老师

Go 简易登陆功能:go-redis Hash

我们要实现的功能是通过 Redis 来存储用户信息,但是存储之前我们先要从数据库里拿到这些数据。

我们先假装有一个数据库,因为要简单,所以直接用代码伪装一个数据库。

但是再此之前需要先定义一个 User 类。

type User struct {
	Id int64 `json:"id" redis:"id"`
	Username string `json:"username" redis:"username"`
	Password string `json:"password" redis:"password"`
	Email string `json:"email" redis:"email"`
	Url string `json:"url" redis:"url"`
}

然后自己假装一个数据库(需要有注册、获取功能):

type YouDB struct {
	users map[string]*User
}

func (y *YouDB) Register(user *User) {
	y.users[user.Username] = user
}

func (y *YouDB) GetUser(username string) (*User, error) {
	user, ok := y.users[username]
	if !ok {
		return &User{}, errors.New("用户不存在")
	}
	return user, nil
}

然后因为是测试而已,所以需要自己新建一些用户信息,用上面的 YouDB 类创建一个数据库:

func BeforeDb() *YouDB {
	db := &YouDB{
		users: make(map[string]*User),
	}
	db.Register(&User{
		Id:       1,
		Username: "zhangsan",
		Password: "123456",
		Email:    "123@qq.com",
		Url:      "https://200011.net",
	})
	db.Register(&User{
		Id:       2,
		Username: "lisi",
		Password: "321123",
		Email:    "321@qq.com",
		Url:      "https://blog.200011.net",
	})
	return db
}

然后就是 Login 函数了:

func Login(username string, password string) {
	// 连接 redis
	rdb := connect.Connect()
	defer rdb.Close()
	// 获取 context
	ctx := context.Background()
	// 用户 Key 前缀
	prefix := "user:"
	// 当前待登陆用户的 key
	key := prefix + username
	// 执行操作
	getAll := rdb.HGetAll(ctx, key)
	userCache, err := getAll.Result()
	user := new(User)
	if err == nil {
		if len(userCache) == 0 {
			// 如果 HGetAll 的结果为空,则用户不在 Redis,需要到数据库读取数据
			fmt.Println("用户缓存不在 Redis,开始从数据库读取数据")
			// 从数据库读取用户信息
			db := BeforeDb()
			mUser, err := db.GetUser(username)
			if err != nil {
				fmt.Printf("登陆失败:%s\n", err.Error())
				return
			}
			user = mUser
			// 将 user 使用 Hash 写入 Redis
			err = rdb.HSet(ctx, key, user).Err()
			if err != nil {
				fmt.Printf("登陆失败:%s\n", err.Error())
				return
			}
			fmt.Printf("User: %s, 已写入缓存\n", user.Username)
		} else {
			// 如果已经存在 Redis 中
			fmt.Println("缓存hit")
			// 将用户的信息从 Hash 读取到 user
			getAll.Scan(user)
		}
		// 判断密码是否正确
		if user.Password == password {
			fmt.Println("登陆成功")
		} else {
			fmt.Println("登陆失败:密码错误")
		}
	} else {
		fmt.Println(err.Error())
	}
	fmt.Println("=====================================")
}

简单测试一下:

func TestLogin(t *testing.T) {
	Login("zhangsan", "123456")
	Login("lisi", "123123")
}

输出如下:

代码思路:说透 Redis7:第 9 篇

评论

Copyright © 2014 - 2025 油老师.