Go 语言微服务框架 Kratos 操作 MySQL 和 Redis

教育   2024-12-30 08:01   湖南  

欢迎点击下方👇关注我,记得星标哟~

文末会有重磅福利赠送

01 

介绍

Go 语言微服务框架 Kratos 不限制使用任何第三方库,我们可以根据个人喜好选择第三方库。

本文我们以 XORM 和 Go Redis 为例,介绍 Kratos 微服务框架怎么集成 XORM[1] 和 Go Redis[2] 操作 MySQL 和 Redis。

02 

集成 XORM 和 Go Redis

创建项目

kratos new blog

安装 MySQL 驱动

示例代码:

go get -u github.com/go-sql-driver/mysql

安装 xorm

示例代码:

go get xorm.io/xorm

安装 go redis

示例代码:

go get github.com/redis/go-redis/v9

客户端

编写文件 blog/internal/data/data.go

导入第三方库

import (
 _ "github.com/go-sql-driver/mysql"
 "github.com/redis/go-redis/v9"
 "xorm.io/xorm"
)

添加 xorm 和 go redis 客户端

// Data .
type Data struct {
// TODO wrapped database client
 dbEngine *xorm.Engine
 rdb      *redis.Client
}

// NewData .
func NewData(c *conf.Data, logger log.Logger, dbEngin *xorm.Engine, rdb *redis.Client) (*Data, func()error) {
 cleanup := func() {
  log.NewHelper(logger).Info("closing the data resources")
 }
return &Data{
  dbEngine: dbEngin,
  rdb:      rdb,
 }, cleanup, nil
}

创建函数 NewDbEngine 和 NewRedisClient

func NewDbEngine(c *conf.Data) (dbEngine *xorm.Engine, err error) {
 dbEngine, err = xorm.NewEngine(c.Database.Driver, c.Database.Source)
 return
}

func NewRedisClient(c *conf.Data) (rdb *redis.Client) {
 rdb = redis.NewClient(&redis.Options{
  Addr:     c.Redis.Addr,
  Password: c.Redis.Password,
  DB:       int(c.Redis.Db),
 })
 return
}

添加 Wire 提供者

编写 blog/internal/data/data.go 文件,添加 NewDbEngine, NewRedisClient

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewGreeterRepo, NewDbEngine, NewRedisClient)

03 

使用 XORM 和 Go Redis

我们以操作用户表 user 为例,介绍怎么使用 XORM 和 Go Redis。

数据库表 user 表结构

CREATE TABLE`user` (
`id`bigint(20unsignedNOTNULL AUTO_INCREMENT COMMENT'id',
`name`varchar(30NOTNULLDEFAULT''COMMENT'user name',
`email`varchar(50NOTNULLDEFAULT''COMMENT'user email',
`password`varchar(30NOTNULLDEFAULT''COMMENT'user password',
`created`int(11NOTNULLDEFAULT'0'COMMENT'create time',
`updated`int(11NOTNULLDEFAULT'0'COMMENT'updated time',
  PRIMARY KEY (`id`),
KEY`idx_user` (`name`)
ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COMMENT='user'

Usecase 层

首先,我们需要在 blog/internal/biz 目录中,创建文件 user.go

在 user.go 文件中,我们定义 User 结构体,定义 UserRepository,定义 UserUsecase

定义 User 结构体

type User struct {
 Id       int64 `xorm:"autoincr""`
 Name     string
 Email    string
 Password string
 Created  int64 `xorm:"created""`
 Updated  int64 `xorm:"updated""`
}

定义 UserRepository

type UserRepository interface {
 Create(ctx context.Context, user *User) (int64, error)
 Get(ctx context.Context, user *User) (bool, error)

 RedisGetUser(ctx context.Context, id int64) (val string, err error)
 RedisSetUser(ctx context.Context, id int64, val interface{}, expiration time.Duration) (err error)
}

定义 UserUsecase

type UserUsecase struct {
 userRepo UserRepository
}

func NewUserUsecase(userRepo UserRepository) *UserUsecase {
return &UserUsecase{
  userRepo: userRepo,
 }
}

func (u *UserUsecase) CreateUser(ctx context.Context, user *User) (id int64, err error) {
 id, err = u.userRepo.Create(ctx, user)
if err != nil {
return
 }
if id > 0 {
var b []byte
  b, err = json.Marshal(user)
if err != nil {
   return
  }
  err = u.userRepo.RedisSetUser(ctx, user.Id, string(b), time.Second*300)
if err != nil {
   return
  }
 }
return
}

添加 Wire 提供者

编写 blog/internal/biz/biz.go 文件,添加 NewUserUsecase

// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewGreeterUsecase, NewUserUsecase)

Repository 层

然后,我们需要在 blog/internal/data 目录中,创建 user.go 文件和 redis.go 文件。

在 user.go 文件和 redis.go 文件中,我们实现 UserRepository 接口中的方法。

MySQL

type userRepository struct {
 data *Data
}

func NewUserRepository(data *Data) biz.UserRepository {
return &userRepository{
  data: data,
 }
}

func (u *userRepository) Create(ctx context.Context, user *biz.User) (id int64, err error) {
var affected int64
 affected, err = u.data.dbEngine.InsertOne(user)
if err != nil {
return
 }
if affected > 0 {
  id = user.Id
 }
return
}

Redis

func (u *userRepository) RedisSetUser(ctx context.Context, id int64, val interface{}, expiration time.Duration) (err error) {
 key := fmt.Sprintf("user:%d", id)
 err = u.data.rdb.Set(ctx, key, val, expiration).Err()
 if errors.Is(err, redis.Nil) {
  err = nil
  return
 }
 return
}

添加 Wire 提供者

编写 blog/internal/data/data.go 文件,添加 NewUserRepository

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewGreeterRepo, NewDbEngine, NewUserRepository, NewRedisClient)

Delivery 层

再然后,我们编辑 blog/internal/service/user.go 文件,完善该文件中的方法。

type UserService struct {
 pb.UnimplementedUserServer
 userUcase *biz.UserUsecase
}

func NewUserService(userUcase *biz.UserUsecase) *UserService {
return &UserService{
 userUcase: userUcase,
 }
}

func (s *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserReply, error) {
 user := &biz.User{
  Name:     req.Name,
  Email:    req.Email,
  Password: req.Password,
 }
 id, err := s.userUcase.CreateUser(ctx, user)
if err != nil {
returnnil, err
 }
 name := fmt.Sprintf("user_%d", id)
return &pb.CreateUserReply{
  Name: name,
 }, nil
}

添加 Wire 提供者

编写 blog/internal/service/service.go 文件,添加 NewUserService

// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewGreeterService, NewUserService)

注册服务

最后,进入 blog/internal/server 目录,编写 http.go 和 grpc.go 文件,添加函数签名 user *service.UserService

并且,分别在函数体中注册服务。

示例代码:

HTTP

v1_user.RegisterUserHTTPServer(srv, user)

gRPC

v1_user.RegisterUserServer(srv, user)

Wire 生成代码

进入目录 blog/cmd/blog,执行 wire 命令。

cd blog/cmd/blog
wire

项目运行和测试

Kratos 运行

kratos run

curl 请求示例

curl -H "Content-Type: application/json" -X POST -d '{"name":"tony", "email":"tony@gmail.com", "password":"tony"}' http://192.168.110.209:8000/user/create

04 

总结

本文我们通过示例代码,介绍 Kratos 微服务框架怎么集成第三方库,操作 MySQL 和 Redis。

早日上岸!unsetunset

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。

点击下方文章,看看他们是怎么找到好工作的!

Go就业陪跑训练营,辅导到就业为止!

Java就业陪跑训练营,辅导到就业为止!

我们又出成绩啦!大厂Offer集锦!遥遥领先!

王中阳
公司技术总监,创办就业陪跑服务,辅导学员拿到600多个offer。专注程序员的就业辅导、简历优化、模拟面试等。
 最新文章