go-zero:尝试使用go-zero的工具goctl进行model,controller代码生成,配置数据库,实现FindAll方法,查询数据库全部数据

Posted freewebsys

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go-zero:尝试使用go-zero的工具goctl进行model,controller代码生成,配置数据库,实现FindAll方法,查询数据库全部数据相关的知识,希望对你有一定的参考价值。

目录

前言


本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/128707849

未经博主允许不得转载。
博主CSDN地址是:https://blog.csdn.net/freewebsys
博主掘金地址是:https://juejin.cn/user/585379920479288
博主知乎地址是:https://www.zhihu.com/people/freewebsystem

1,关于go-zero框架


项目地址:
https://go-zero.dev/cn/
go-zero 是一个集成了各种工程实践的 web 和 rpc 框架

高性能
内建服务发现、负载均衡
内建限流
自适应熔断
自适应降载
自动触发,自动恢复
超时级联控制
自动缓存控制
链路跟踪、统计报警等
高并发支撑,稳定保障流量洪峰下的服务稳定

2,使用goctl 生成代码,安装工具


https://go-zero.dev/cn/docs/goctl/goctl

官方demo网站:

代码自动生成
go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的 api 文件一键生成 Go, ios, android, Kotlin, Dart, TypeScript, javascript 代码,并可直接运行。

安装代码:

export GOPROXY=https://goproxy.cn/,direct 
go install github.com/zeromicro/go-zero/tools/goctl@latest

goctl -v
goctl version 1.4.3 darwin/amd64

先创建一个新项目:

goctl api new userDemo  -style goZero

cd userDemo

3,使用goctl 生成数据库model的crud代码


针对 userInfo 做CRUD,生成 model 代码:

比如一个用户表,放到 sql/user_info.sql 文件中:

CREATE TABLE IF NOT EXISTS  `user_info` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `name` varchar(200) NOT NULL COMMENT '用户名',
  `password` varchar(200) NOT NULL COMMENT '密码',
  `status` tinyint(1) NOT NULL COMMENT '状态',
  `type` tinyint(1) NOT NULL COMMENT '类型',
 
  PRIMARY KEY (`id`)
  
) ENGINE=InnoDB  AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT="用户信息表";

然后生成model 的 curd 代码:

注意 -c 参数表示是否带缓存:
生成不带缓存的代码:
goctl model mysql ddl -src="./sql/*.sql" -dir="./model"  -style goZero

生成代码缓存的代码:
goctl model mysql ddl -src="./sql/*.sql" -dir="./model" -c -style goZero

会有类似,不带缓存查询,直接硬编码了:

func (m *defaultUserInfoModel) FindOne(ctx context.Context, id int64) (*UserInfo, error) 
	query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userInfoRows, m.table)
	var resp UserInfo
	err := m.conn.QueryRowCtx(ctx, &resp, query, id)
	switch err 
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	

带缓存查询:

func (m *defaultUserInfoModel) FindOne(ctx context.Context, id int64) (*UserInfo, error) 
	userInfoIdKey := fmt.Sprintf("%s%v", cacheUserInfoIdPrefix, id)
	var resp UserInfo
	err := m.QueryRowCtx(ctx, &resp, userInfoIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface) error 
		query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userInfoRows, m.table)
		return conn.QueryRowCtx(ctx, v, query, id)
	)
	switch err 
	case nil:
		return &resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	

4,使用goctl 生成controller代码


最关键的就是这个 userDemo.api 的文件定义,和其他框架不同,这个配置定义的是接口的API。

  * 可以在 servicecontext.go 里面传递依赖给 logic,比如 mysql, redis 等
  * 在 api 定义的 get/post/put/delete 等请求对应的 logic 里增加业务处理逻辑

定义 userDemo.api 的配置,做个 crud 的 api 接口:

type UserInfo 
	Id       int    `form:"id,optional"`
	Name     string `form:"name"`
	Password string `form:"password"`
	Status   int    `form:"status,optional"`
	Type     int    `form:"type,optional"`


type UserInfoResponse 
	Id     int    `form:"id"`
	Name   string `form:"name"`
	Status int    `form:"status"`
	Type   int    `form:"type"`


type SearchRequest 
	Name string `form:"name,optional"`


type IdRequest 
	Id int `form:"id"`


type CommonResponse 
	Status  int    `json:"status"`
	Message string `json:"message"`


type ListResponse 
	Status  int        `json:"status"`
	Message string     `json:"message"`
	Data    []UserInfo `json:"data"`


service userDemo-api 
	@handler userInfoListHandler
	get /userInfo/list(SearchRequest) returns (ListResponse)
	
	@handler viewUserInfoHandler
	get /userInfo/view(IdRequest) returns (UserInfoResponse)
	
	@handler saveUserInfoHandler
	post /userInfo/save(UserInfo) returns (CommonResponse)
	
	@handler deleteUserInfoHandler
	post /userInfo/delete(IdRequest) returns (CommonResponse)

重新生成代码:

# 需要把之前的 controller 和 logic 代码删除再生成。
goctl api go -api userDemo.api -dir . -style goZero

go mod init 
go mod tidy 

#然后再启动服务:
go run userdemo.go -f etc/userDemo-Api.yaml 

6,增加数据库,日志配置


然后修改 config 的配置和 yaml 配置:

Name: userDemo-api
Host: 0.0.0.0
Port: 8888

Redis:
  Host: localhost:6379
  Type: node
  Pass: 
DB:
  DataSource: go-demo:go-demo123@tcp(127.0.0.0:3306)/go_demo?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
Cache:
  - Host: localhost:6379
    Pass: 

Log:
  ServiceName: userDemo-api
  Level: severe
  Mode: file

修改 config 类:

package config

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

type Config struct 
	rest.RestConf
	logx.LogConf

	DB struct 
		DataSource string
	



启动类里面增加日志:

	var c config.Config
	conf.MustLoad(*configFile, &c)

	// logx 根据配置初始化
	// https://go-zero.dev/cn/docs/blog/tool/logx/
	logx.MustSetup(c.LogConf)
	// grace close log
	proc.AddShutdownListener(func() 
		logx.Close()
	)

......

然后增加 findAll 方法:

func (m *defaultUserInfoModel) FindAll(ctx context.Context) ([]*UserInfo, error) 
	query := fmt.Sprintf("select %s from %s ", userInfoRows, m.table)

	var resp []*UserInfo
	err := m.conn.QueryRowsCtx(ctx, &resp, query)
	switch err 
	case nil:
		return resp, nil
	default:
		return nil, err
	

controller 里面代码使用 copy 进行转换,因为 model 的类和 logic 包对应的类包不一样:

func (l *UserInfoListLogic) UserInfoList(req *types.SearchRequest) (resp *types.ListResponse, err error) 
	// todo: add your logic here and delete this line
	logx.WithContext(l.ctx).Info("######## query UserInfoList ########")

	userInfoList, err := l.svcCtx.UserInfoModel.FindAll(l.ctx)

	if err != nil 
		return nil, err
	

	var userInfoListTmp []types.UserInfo //
	_ = copier.Copy(&userInfoListTmp, userInfoList)

	return &types.ListResponse
		Status:  200,
		Message: "success",
		Data:    userInfoListTmp,
	, nil


然后启动之后 controller 里面就可以获得数据了,终于调试好了。

然后访问:
http://localhost:8888/userInfo/list

"status":200,"message":"success","data":["Id":1,"Name":"11","Password":"22","Status":1,"Type":1,"Id":2,"Name":"33","Password":"44","Status":5,"Type":2,"Id":3,"Name":"11","Password":"22","Status":1,"Type":1,"Id":4,"Name":"33","Password":"44","Status":5,"Type":2,"Id":5,"Name":"11","Password":"22","Status":1,"Type":1,"Id":6,"Name":"33","Password":"44","Status":5,"Type":2]

7,总结


总体上感觉 go-zero 还是比较好上手的,使用起来也是非常的方便,但是 curd 的 model 里面的查询略少。
而且没有分页查询的数据,需要自己组装。把分页其他的啥的模板都修改下。
相比kratos 这个算是简单的了,因为kratos采用了ddd的设计方式,更优雅。
但是代码分布的略复杂,需要学习下,

本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/128707849

以上是关于go-zero:尝试使用go-zero的工具goctl进行model,controller代码生成,配置数据库,实现FindAll方法,查询数据库全部数据的主要内容,如果未能解决你的问题,请参考以下文章

go-zero框架工具安装

go-zero效率工具一览图

一文读懂云原生 go-zero 微服务框架

go-zero我是如何把gorm整合进go-zero的?

go-zero微服务开发环境搭建

go-zero微服务开发环境搭建