go-zero笔记

安装:

$ mkdir <project name> && cd <project name> # project name 为具体值
$ go mod init <module name> # module name 为具体值
$ go get -u github.com/zeromicro/go-zero@latest

常见问题

1. 设置了 GOPROXY 后,依赖还是拉不下来?

确认 GO111MODULE 是否开启

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

goctl 安装

概述

goctl 是 go-zero 的内置脚手架,是提升开发效率的一大利器,可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。

文档:goctl 安装 | go-zero Documentation

这里只是安装完了,但是项目还没有正式开始生成

api demo 代码生成

代码生成

# 创建工作空间并进入该目录
$ mkdir -p ~/workspace/api && cd ~/workspace/api
# 执行指令生成 demo 服务
$ goctl api new demo
Done.

执行完指令后,会在当前目录下生成一个 demo 目录,该目录下包含了一个最小化的 HTTP 服务,我们来查看一下该服务的目录结构。

# 进入 demo 服务目录
$ cd ~/workspace/api/demo
# 查看文件列表
$ ls
demo.api demo.go  etc      go.mod   internal
# 查看目录接口
$ tree
.
├── demo.api
├── demo.go
├── etc
│   └── demo-api.yaml
├── go.mod
└── internal
    ├── config
    │   └── config.go
    ├── handler
    │   ├── demohandler.go
    │   └── routes.go
    ├── logic
    │   └── demologic.go
    ├── svc
    │   └── servicecontext.go
    └── types
        └── types.go

其中

启动:go run demo.go 或者 cd进入目录,然后go run .

定义路由

有.api文件,该文件可以自定义位置。

然后编辑器安装goctl。可以通过goctl生成路由信息

逻辑编写

logic/xxx.go

package logic

import (
    "context"

    "ginGoZeroProject/api/internal/svc"
    "ginGoZeroProject/api/internal/types"

    "github.com/zeromicro/go-zero/core/logx"
)

type ApiLogic struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewApiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ApiLogic {
    return &ApiLogic{
       Logger: logx.WithContext(ctx),
       ctx:    ctx,
       svcCtx: svcCtx,
    }
}

func (l *ApiLogic) Api(req *types.Request) (resp *types.Response, err error) {
    // todo: add your logic here and delete this line 在这里编写具体逻辑
    print(req.Name)
    resp = &types.Response{Message: req.Name}
    return resp, nil
}

RPC生成

# 创建工作空间并进入该目录
$ mkdir -p ~/workspace/rpc && cd ~/workspace/rpc
# 执行指令生成 demo 服务
$ goctl rpc new demo
Done.

文档:gRPC demo 代码生成 | go-zero Documentation

业务逻辑编写流程

1.在api项目/internal/config/config.go。其中。AdminRpcConfig为自定义变量名

2.在api/internal/svc/servicecontext.go

package svc

import (
    "admin.go.bi.gamedatayilehudong.com/admin/internal/config"
    "admin.go.bi.gamedatayilehudong.com/rpc/admin/adminclient"
    "github.com/zeromicro/go-zero/zrpc"
)

type ServiceContext struct {
    Config   config.Config
    AdminRpc adminclient.Admin
}

func NewServiceContext(c config.Config) *ServiceContext {
    adminRpc := zrpc.MustNewClient(c.AdminRpdConfig)

    return &ServiceContext{
       Config:   c,
       AdminRpc: adminclient.NewAdmin(adminRpc),
    }
}

api调用rpc服务

1.api/etc/api-api.yaml 新增rpc地址

Name: api-api
Host: 0.0.0.0
Port: 8888
# 以下新增
AdminRPCConfig: # 管理RPC配置 文件目录在internal/config/config.go中
  Target: dns:///127.0.0.1:8080 # RPC目标地址

2.在api的logic代码里面

通过svcCtx调用【api/internal/svc/servicecontext.go】定义的结构体,再调用rpc里面的方法
all, err := l.svcCtx.AdminRpc.Ping(l.ctx, &admin.Request{Ping: "ping"})

调用model

这里用gorm的操作

  • 安装gorm
go get -u gorm.io/gorm     
go get -u gorm.io/driver/mysql 
  • 在根目录创建common,用来存储自动生成脚本,该目录在哪个项目都可以,主要是取决于哪个项目调用,其中,conn为链接脚本,gen为自动生成脚本。model为gen.go执行了之后自动生成文件

  • conn.go代码
package conn

import (
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var DB *gorm.DB

type DbConfig struct {
    Database string
    Username string
    Pwd      string
    Host     string
}

func NewDb(config DbConfig) {
    dsn := fmt.Sprintf("%s:%s@(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
       config.Username,
       config.Pwd,
       config.Host,
       config.Database,
    )
    var err error
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})

    if err != nil {
       fmt.Printf("conn db err:%s", err)
    }
}
  • gen.go代码
package main

import (
    "flag"
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gen"
    "gorm.io/gorm"
)

var t string

func init() {
    flag.StringVar(&t, "t", "", "database")
    flag.Parse()

    if t == "" {
       panic("未選擇表")
    }
}

func main() {
    g := gen.NewGenerator(gen.Config{
       OutPath: "../model",
       Mode:    gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
    })
    database := "yile_xxxs"
    dsn := fmt.Sprintf("xxx:xxxx@(xxxx:xxx)/%s?charset=utf8mb4&parseTime=True&loc=Local", database)
    gormdb, _ := gorm.Open(mysql.Open(dsn))
    g.UseDB(gormdb) // reuse your gorm db
    g.GenerateModel(t)
    g.Execute()
}
  • 配置文件,就是.yaml文件
# 以下为新增配置。类似.env文件
DbConfig:
  Database: "yile_xxx"
  Username: "roxxx"
  Pwd: "sdasxxx"
  Host: "gz-xx.xxxcom:5555"
  • 进到这个目录执行go run . -t 表名,就会自动生成表的结构体。就是model里面的数据
  • config注册服务

  • svc里面的context初始化db对象。这样就把db对象放到了全局里面

  • 使用的时候需要.WithContext(l.ctx),以下是实例,其中,这里有个注意的点是,go的查找数据是把数据存储到结构体里面。并不是存储到接收的变量。所以要打印数据就是打印结构体的数据
func (l *PingLogic) Ping(in *user.Request) (*user.Response, error) {
    var infos []model.BasicsUserInfo // 定义一个存储BasicsUserInfo结构的切片infos
    first := conn.DB.WithContext(l.ctx).Find(&infos, []int{2106810, 2106811, 2106812}) // 在数据库中根据给定的id查找BasicsUserInfo记录,并将结果存储在infos中

    if first.Error != nil { // 如果查找过程中出现错误
       fmt.Printf("ERROR: %v\n", first.Error) // 打印错误信息
       return nil, first.Error // 返回错误
    }

    for _, info := range infos { // 遍历infos切片中的每个记录
       fmt.Printf("Retrieved user info: %+v\n", info) // 打印获取到的用户信息
    }

    return &user.Response{Pong: in.Ping}, nil // 返回带有Pong字段的user.Response结构和nil错误

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镜中先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值