IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Go-Zero 数据库实战:配置、建模与业务逻辑一体化

    王中阳Go发表于 2024-07-26 14:59:47
    love 0

    前言

    在之前的几篇文章中,我们深入学习了Go-Zero框架的实战应用,包括模板定制化、API定义、抽奖算法设计等内容。本文将继续探索Go-Zero框架的实践技巧,并介绍一些与数据库操作相关的主题。

    在现代应用程序开发中,对数据库的操作是非常常见且重要的一部分。Go-Zero框架提供了强大的数据库支持,使得我们可以轻松地进行数据库访问和操作。本文将重点介绍如何使用Go-Zero框架进行数据库的增删改查(CRUD)操作,并提供详细的示例代码和解释。

    在本文中,我们将使用MySQL数据库作为示例,并结合Go-Zero框架的相关组件,如数据模型(Model)、事务处理、连接池等,来展示数据库操作的最佳实践。无论你是初学者还是有一定经验的开发者,本文都将为你提供有用的信息和技巧,帮助你更好地理解和应用Go-Zero框架中的数据库操作。

    在阅读本文之前,请确保你已经按照前几篇文章中的说明进行了必要的准备工作,包括安装所需的工具和设置项目环境。同时,本文假设你已经具备一定的数据库基础知识,如表的创建、数据的插入和查询等。

    通过学习本文,你将掌握以下内容:

    • 如何配置和初始化数据库连接;
    • 如何使用Go-Zero框架的Model组件进行数据表的创建和映射;
    • 如何进行常见的CRUD操作,包括数据的插入、查询、更新和删除;
    • 如何处理数据库事务;
    • 实现用户注册业务逻辑。

    我们鼓励你跟随示例代码,动手实践,并根据自己的需求进行定制和扩展。无论是为了学习Go-Zero的数据库操作,还是为了解决具体的业务问题,本文都将为你提供实用的指导和技巧。

    祝你阅读愉快,并从中获得所需的知识和灵感!

    实战前准备

    本次实战我们是建立在(六)Go-Zero实战之docker开发环境部署 基础之上,如果没有学习过,可以点击跳转学习,然后再看本文哦!

    本次实战采用的是docker部署,请提前准备好相关环境,关于docker环境的搭建在(六)Go-Zero实战之docker开发环境部署 中也有讲解,不了解小伙伴建议先行实战docker环境搭建哦!

    目录结构说明

    • 在app下面我们将会新建一个服务comment,表示晒单评论服务,deploy/sql存放的是我们的建表语句,相关语句将会在接下来的讲解中给大家。

    实战

    配置docker组件

    • 在docker-commpose-env.yml中添加如下配置mysql

      mysql:
        image: mysql/mysql-server:8.0.28
        container_name: mysql
        environment:
          # 时区上海 - Time zone Shanghai (Change if needed)
          TZ: Asia/Shanghai
          # root 密码 - root password
          MYSQL_ROOT_PASSWORD: xxxxxx #这里填上mysql的密码
        ports:
          - 33069:3306
        volumes:
          # 数据挂载 - Data mounting
          - ./data/mysql/data:/var/lib/mysql
          # 日志
        command:
          # 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配) 
          # Modify the Mysql 8.0 default password strategy to the original strategy (MySQL8.0 to change its default strategy will cause the password to be unable to match)
          --default-authentication-plugin=mysql_native_password
          --character-set-server=utf8mb4
          --collation-server=utf8mb4_general_ci
          --explicit_defaults_for_timestamp=true
          --lower_case_table_names=1
        privileged: true
        restart: always
        networks:
          - testProject_net
    • 在本次实战中我们会使用到缓存(使用sqlc库),因此也进行了redis的配置。如果不想走缓存,可以使用sqlx库,后续根据需求再添加缓存。
    • 在docker-commpose-env.yml中添加如下配置redis

      #redis容器 - Redis container
      redis:
        image: redis:6.2.5
        container_name: redis
        ports:
          - 36379:6379
        environment:
          # 时区上海 - Time zone Shanghai (Change if needed)
          TZ: Asia/Shanghai
        volumes:
          # 数据文件 - data files
          - ./data/redis/data:/data:rw
        command: "redis-server --requirepass G62m50oigInC30sf  --appendonly yes"
        privileged: true
        restart: always
        networks:
          - testProject_net
    • 在进行复制粘贴的时候需要注意缩进哦!

    重新启动项目所依赖的环境

    $ docker-compose -f docker-compose-env.yml up -d

    Navicate连接数据库

    Go-Zero操作数据库

    go-zero提供了两个操作数据库的库,分别是sqlc和sqlx。区别是前者带缓存,后者不带缓存。

    我们先在(六)Go-Zero实战之docker开发环境部署 中创建的usercent服务进行gozero操作数据库相关内容的学习

    • tips:相关服务和表结构在(六)Go-Zero实战之docker开发环境部署 中已经实现,如果本地没有的小伙伴可以先进行(六)的学习和操作哦!
    • 在(六)Go-Zero实战之docker开发环境部署 中我们已经定义了两个RPC接口,接下来我们通过实现这两个register接口展示如何使用gozero操作数据库。

    使用脚本生成数据库对应的model

    • tips:这一小节的内容在(三)Go-Zero和goctl:解锁微服务开发的神器,快速上手指南 中有过详细的讲解,如果有不清楚的小伙伴可以点击这里进行回顾哦!本节仅进行操作以及效果展示。
    • 脚本如下(放在目录的deploy/script/mysql/genModel.sh下):
    #!/usr/bin/env bash
    
    # 使用方法:
    # ./genModel.sh lottery lottery
    # ./genModel.sh lottery prize
    # ./genModel.sh looklook_usercenter user_contact
    # 再将./genModel下的文件剪切到对应服务的model目录里面,记得改package
    
    #生成的表名
    tables=$2
    #表生成的genmodel目录
    modeldir=./genModel
    
    # 数据库配置
    host=127.0.0.1
    port=33069
    dbname=$1
    username=root
    passwd=PXDN93VRKUm8TeE7
    template=../../goctl/1.6.1
    
    echo "开始创建库:$dbname 的表:$2"
    goctl model mysql datasource -url="${username}:${passwd}@tcp(${host}:${port})/${dbname}" -table="${tables}" -dir="${modeldir}" -cache=true --home="${template}" --style=goZero
    • 使用GitBash打开deploy/script/mysql目录,执行脚本

    • 将相关代码放到model下

    • 把包名改成model

    • 配置文件中加入如下配置,用于jwt鉴权以及mysql、redis连接配置的获取

    package config
    
    import (
        "github.com/zeromicro/go-zero/core/stores/cache"
        "github.com/zeromicro/go-zero/zrpc"
    )
    
    type Config struct {
        zrpc.RpcServerConf
        CheckinRpcConf zrpc.RpcClientConf
        JwtAuth        struct {
            AccessSecret string
            AccessExpire int64
        }
        DB struct {
            DataSource string
        }
        Cache cache.CacheConf
    }
    • svc下的serviceContext加入如下配置,用于获取mysql连接

    package svc
    
    import (
        "github.com/zeromicro/go-zero/core/stores/redis"
        "github.com/zeromicro/go-zero/core/stores/sqlx"
        "testProject/app/usercenter/cmd/rpc/internal/config"
        "testProject/app/usercenter/model"
    )
    
    type ServiceContext struct {
        Config    config.Config
        UserModel model.UserModel
    
        RedisClient *redis.Redis
    }
    
    func NewServiceContext(c config.Config) *ServiceContext {
        sqlConn := sqlx.NewMysql(c.DB.DataSource)
    
        return &ServiceContext{
            UserModel: model.NewUserModel(sqlConn, c.Cache),
            Config:    c,
        }
    }
    • rpc/etc/usercenter.yaml加上jwtAuth配置
    #jwtAuth
    JwtAuth:
      AccessSecret: ae0536f9-6450-4606-8e13-5a19ed505da0
      AccessExpire: 31536000
    • 注册model

    UserModel:        model.NewUserModel(sqlConn, c.Cache),
    • 这样我们就可以在userModel下写我们自己的sql操作了

    事务操作

    • sqlc为我们提供了事务操作,相关源码如下:

    • 我们可以基于官方提供的TransactCtx方法,封装自己的事务处理方法

      • 首先在userModel里面注册Trans方法,如下图所示

    Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error
    • 接着写这个方法的实现,其实就是对原本的函数进行了一个封装。

    func (m *defaultUserModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
        return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
           return fn(ctx, session)
        })
    }
    • 通过这个例子,我们可以知道gozero如何注册自己的数据库操作方法,以及了解到如何进行事务操作。

    注册业务逻辑的实现

    • 首先我们先在tool下新增encryption.go文件,增加一个md5加密字符串的函数

    func Md5ByString(str string) string {
        m := md5.New()
        _, err := io.WriteString(m, str)
        if err != nil {
            panic(err)
        }
        arr := m.Sum(nil)
        return fmt.Sprintf("%x", arr)
    }
    • 在logic/registerLogic.go里面编写我们的注册逻辑,注册业务代码如下
    func (l *RegisterLogic) Register(in *pb.RegisterReq) (*pb.RegisterResp, error) {
        if err := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
           user := new(model.User)
           if len(in.Password) > 0 {
              user.Password = tool.Md5ByString(in.Password)
           }
           insertResult, err := l.svcCtx.UserModel.Insert(ctx, user)
           if err != nil {
              return errors.Wrapf(err, "Register db user Insert err:%v,user:%+v", err, user)
           }
           lastId, err := insertResult.LastInsertId()
           if err != nil {
              return errors.Wrapf(err, "Register db user insertResult.LastInsertId err:%v,user:%+v", err, user)
           }
           fmt.Println("lastId:", lastId)
    
           return nil
        }); err != nil {
           logx.Error("Register:", err)
           return nil, err
        }
    
        return &usercenter.RegisterResp{}, nil
    
    }
    • tips:这个是最简单的插入一条数据的逻辑,实际生产中我们往往需要添加各种校验以及登录回调,jwt返回等,根据实际需求进行修改。如果读者朋友有需求,后续文章我们也会完善这个注册逻辑。
    • 可以看见我们实际调用了Insert方法进行了插入操作。gozero框架的默认模板帮我们封装好了常规的增删改查操作,我们可以直接调用即可,如果有额外需求我们可以在userModel.go定义自己的sql查询方法,或者自定义我们自己的goctl,关于自定义模板可以看我前面的文章(四)Go-Zero自定义goctl实战:定制化模板,加速你的微服务开发效率哦!
    • 接下来我们简单看一下模板中对于增删查改方法的实现
    • 插入操作

    • 删除操作

    • 更新操作

    • 查询操作

    • 更多的数据库操作建议可以查看官方文档mysql 代码生成 | go-zero Documentation,本教程更注重于实践操作以及代码实现。

    测试与验证

    • 编写完业务后我们启动服务,关于服务启动在(三)Go-Zero和goctl:解锁微服务开发的神器,快速上手指南 中有详细讲解,这里不进行重复讲解。

    • 可以看见成功进行了用户注册,说明插入操作有效。

    结语

    至此,我们已经完成了数据库相关配置,以及通过用户服务和注册接口了解到了常规的增删改查操作。

    关于更详细的实现,如果有小伙伴有需求,我们可以单独拿一节课来进行详细的拆分讲解。

    本篇文章介绍了Go-Zero中的数据库操作,并提供了常用的命令示例。通过学习和实践,我们可以更加熟练地使用Go-Zero进行高效的数据库操作。在后续的文章中,我们将进一步探索数据库操作的高级用法和技巧,为小伙伴们提供更多的参考。

    欢迎关注 ❤

    我的文章都首发在同名公众号:王中阳

    需要简历优化或者就业辅导,可以直接加我微信:wangzhongyang1993,备注:sf



沪ICP备19023445号-2号
友情链接