当前位置: 首页 > news >正文

基于go-zero二次开发的脚本

param=$2
# 字符串风格格式为:DemoName
model_name=$(echo "${param}" | awk -F '_' '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2));}1' | tr -d ' ')
# 字符串风格格式为:demoName
struct_name=$(echo "${model_name}" | awk '{print tolower(substr($0,1,1)) substr($0,2)}')
help()
{cat <<- EOF帮助文档:Desc: 基于goctl指令生成代码程序选项如下:api:生成网关和swagger文档,无参数rpc:生成rpc代码和proto文件,参数1:rpc文件名(不带扩展名)proto 只生成base目录下的proto文件,注意路径,参数1:basemysql:生成model和crud代码,参数1:源文件名(不带扩展名)docker:打包docker镜像,参数1:main文件名(不带扩展名),参数2:版本号Usage:./generate_code.sh api./generate_code.sh rpc user./generate_code.sh proto base./generate_code.sh mysql user./generate_code.sh mysql user v1.0.0
EOFexit 0
}# 生成CRUD的方法
gen()
{# 获取要修改的文件名filename=./dao/mysql/model/$(echo "${param}" | tr -d '_')model.go# 获取行号,用来判断是否需要修改line_number=$(sed -n '$=' ${filename})if [ "$line_number" -lt 30 ]; thencat > "$filename" <<- EOF
package modelimport ("context""database/sql""errors""github.com/doug-martin/goqu/v9"_ "github.com/doug-martin/goqu/v9/dialect/mysql""github.com/zeromicro/go-zero/core/stores/sqlx""upgames-go-microservices/utils/utils"
)var _ ${model_name}Model = (*custom${model_name}Model)(nil)type (// ${model_name}Model is an interface to be customized, add more methods here,// and implement the added methods in custom${model_name}Model.${model_name}Model interface {${struct_name}ModelwithSession(session sqlx.Session) ${model_name}Model// GetTableName 获取表名GetTableName() string// GetCount 根据条件获取数量GetCount(ctx context.Context, ex goqu.Expression) (int64, error)// FindList 根据条件获取列表,排序:map[string]int{"字段":0/1(0-升序(ASC);1-降序(DESC))};分页:[]uint{页码,每页条数}FindList(ctx context.Context, ex goqu.Expression, optionalParams ...any) (*[]${model_name}, error)// FindOnly 根据条件获取单条数据,0-升序(ASC);1-降序(DESC)FindOnly(ctx context.Context, ex goqu.Expression, order ...map[string]int) (*${model_name}, error)// InsertOnly 插入单条数据InsertOnly(ctx context.Context, row *${model_name}, tx ...*sql.Tx) (sql.Result, error)// BatchInsert 批量插入BatchInsert(ctx context.Context, rows []*${model_name}, tx ...*sql.Tx) (sql.Result, error)// UpdateByEx 根据条件更新UpdateByEx(ctx context.Context, record goqu.Record, ex goqu.Expression, tx ...*sql.Tx) (sql.Result, error)// DeleteByEx 根据条件删除数据DeleteByEx(ctx context.Context, ex goqu.Expression, tx ...*sql.Tx) (sql.Result, error)}custom${model_name}Model struct {*default${model_name}Model}
)// New${model_name}Model returns a model for the database table.
func New${model_name}Model(conn sqlx.SqlConn) ${model_name}Model {return &custom${model_name}Model{default${model_name}Model: new${model_name}Model(conn),}
}func (m *custom${model_name}Model) withSession(session sqlx.Session) ${model_name}Model {return New${model_name}Model(sqlx.NewSqlConnFromSession(session))
}// GetTableName 获取表名
func (m *custom${model_name}Model) GetTableName() string {return utils.SetTable(m.table)
}// GetCount 根据条件获取数量
func (m *custom${model_name}Model) GetCount(ctx context.Context, ex goqu.Expression) (int64, error) {query, _, err := goqu.Dialect("mysql").Select(goqu.COUNT(1)).From(utils.SetTable(m.table)).Where(ex).ToSQL()if err != nil {return 0, err}var resp int64err = m.conn.QueryRowCtx(ctx, &resp, query)if err != nil && !errors.Is(err, sqlx.ErrNotFound) {return 0, err}return resp, nil
}// FindList 根据条件获取列表,排序:map[string]int{"字段":0/1(0-升序(ASC);1-降序(DESC))};分页:[]uint{页码,每页条数}
func (m *custom${model_name}Model) FindList(ctx context.Context, ex goqu.Expression, optionalParams ...any) (*[]${model_name}, error) {sql := goqu.Dialect("mysql").Select(&${model_name}{}).From(utils.SetTable(m.table)).Where(ex)if len(optionalParams) > 0 {for _, param := range optionalParams {// 排序if v, ok := param.(map[string]int); ok {for key, value := range v {if value > 0 {sql = sql.Order(goqu.C(key).Desc())} else {sql = sql.Order(goqu.C(key).Asc())}}}// 分页if v, ok := param.([]uint); ok {if len(v) == 2 {sql = sql.Offset((v[0] - 1) * v[1]).Limit(v[1])}}}}query, _, err := sql.ToSQL()if err != nil {return nil, err}var resp []${model_name}err = m.conn.QueryRowsCtx(ctx, &resp, query)if err != nil && !errors.Is(err, sqlx.ErrNotFound) {return nil, err}return &resp, nil
}// FindOnly 根据条件获取单条数据,0-升序(ASC);1-降序(DESC)
func (m *custom${model_name}Model) FindOnly(ctx context.Context, ex goqu.Expression, order ...map[string]int) (*${model_name}, error) {sql := goqu.Dialect("mysql").Select(&${model_name}{}).From(utils.SetTable(m.table)).Where(ex)if len(order) > 0 {for key, value := range order[0] {if value > 0 {sql.Order(goqu.C(key).Desc())} else {sql.Order(goqu.C(key).Asc())}}}query, _, err := sql.Limit(1).ToSQL()if err != nil {return nil, err}var resp ${model_name}err = m.conn.QueryRowCtx(ctx, &resp, query)switch err {case nil:return &resp, nilcase sqlx.ErrNotFound:return nil, ErrNotFounddefault:return nil, err}
}// InsertOnly 插入单条数据
func (m *custom${model_name}Model) InsertOnly(ctx context.Context, row *${model_name}, tx ...*sql.Tx) (sql.Result, error) {query, _, err := goqu.Dialect("mysql").Insert(utils.SetTable(m.table)).Rows(row).ToSQL()if err != nil {return nil, err}var result sql.Resultif len(tx) > 0 {result, err = tx[0].ExecContext(ctx, query)} else {result, err = m.conn.ExecCtx(ctx, query)}return result, err
}// BatchInsert 批量插入
func (m *custom${model_name}Model) BatchInsert(ctx context.Context, rows []*${model_name}, tx ...*sql.Tx) (sql.Result, error) {query, _, err := goqu.Dialect("mysql").Insert(utils.SetTable(m.table)).Rows(rows).ToSQL()if err != nil {return nil, err}var result sql.Resultif len(tx) > 0 {result, err = tx[0].ExecContext(ctx, query)} else {result, err = m.conn.ExecCtx(ctx, query)}return result, err
}// UpdateByEx 根据条件更新
func (m *custom${model_name}Model) UpdateByEx(ctx context.Context, record goqu.Record, ex goqu.Expression, tx ...*sql.Tx) (sql.Result, error) {query, _, err := goqu.Dialect("mysql").Update(utils.SetTable(m.table)).Set(record).Where(ex).ToSQL()if err != nil {return nil, err}var result sql.Resultif len(tx) > 0 {result, err = tx[0].ExecContext(ctx, query)} else {result, err = m.conn.ExecCtx(ctx, query)}return result, err
}// DeleteByEx 根据条件删除数据
func (m *custom${model_name}Model) DeleteByEx(ctx context.Context, ex goqu.Expression, tx ...*sql.Tx) (sql.Result, error) {query, _, err := goqu.Dialect("mysql").Delete(utils.SetTable(m.table)).Where(ex).ToSQL()if err != nil {return nil, err}var result sql.Resultif len(tx) > 0 {result, err = tx[0].ExecContext(ctx, query)} else {result, err = m.conn.ExecCtx(ctx, query)}return result, err
}
EOFelseecho "行数不准确,crud代码已生成"fi
}dockerfile()
{cat > "Dockerfile" <<- EOF
FROM golang:1.22-alpine AS builderLABEL stage=gobuilderENV GOPROXY https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositoriesRUN apk update --no-cache && apk add --no-cache tzdata# 设置工作目录
WORKDIR /build# 加载依赖
ADD go.mod .
ADD go.sum .
RUN go mod download# 复制源代码
COPY . .# 静态编译Go程序
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o app ./service/${struct_name}Service/${param}.go# 第二阶段:运行时镜像,使用空镜像
FROM scratchCOPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt# 设置工作目录
WORKDIR /app# 复制编译好的二进制文件到运行时镜像
COPY --from=builder /build/app .# 运行程序
ENTRYPOINT ["./app"]
# 设置CMD指令来指定参数,默认测试环境的etcd
CMD ["16.162.220.93:2379"]
EOF
}if [ "$1" == "rpc" ]; thengoctl rpc protoc ./proto/source/${param}.proto --go_out=./proto/generate --go-grpc_out=./proto/generate --zrpc_out=./service/${struct_name}Service --style go_zero# 替换omitempty,避免json序列化忽略字段sed -i '' -e '/omitempty/s/,omitempty//g' ./proto/generate/${struct_name}/*.pb.go# 修改客户端文件包名path="./service/${struct_name}Service/${param}_client/"sed -i '' -e "s/package ${param}_client/package client/g" ${path}${param}.go# 将客户端文件移到./proto/client下,删除原来目录mv -f ${path}${param}.go ./proto/clientrm -r ${path}echo "Done."
elif [ "$1" == "api" ]; then# api网关生成goctl api go -api ./proto/source/api/gateway.api -dir ./service/gatewayService -style go_zero# swagger文档生成goctl api plugin -plugin goctl-swagger="swagger -filename gateway.json -host 127.0.0.1:8888" -api ./proto/source/api/gateway.api -dir ./doc/swagger/etcecho "Done."
elif [ "$1" == "proto" ]; then# proto文件生成,base目录下protoc --go_out=.. --go-grpc_out=..  ./proto/source/${param}.protosed -i '' -e '/omitempty/s/,omitempty//g' ./proto/generate/${param}/*.pb.goecho "Done."
elif [ "$1" == "mysql" ]; then# mysql生成代码goctl model mysql ddl --src ./dao/mysql/source/${param}.sql --dir ./dao/mysql/model -i ''genecho "Done."
elif [ "$1" == "docker" ]; thenversion=$3dockerfiledocker build -t "${param}":"${version}" .rm -f Dockerfileecho "Done."
elseecho "参数无效"help
fi

项目目录结构

    • com【业务公共代码】
    • dao【model层】
      • mysql
        • model【生成curd和model的目录】
        • source【表结构】
      • redis
    • doc【文档】
      • swagger【接口文档】
    • proto
      • client【rpc客户端连接】
      • generate【生成rpc目录】
      • source【proto源文件】
    • service【微服务】
      • userService【服务名称】
        • etc【配置文件】
        • internal
          • config【配置结构体】
          • logic【业务逻辑】
          • server【rpc service】
          • svc【初始化依赖】
        • user.go【main入口】
    • utils【公共代码模块】
      • config【配置初始化】
      • consts【常量】
      • gos【协程】
      • kafka【kafka相关】
      • logs【日志相关】
      • mysql【mysql】
      • redis【redis】
      • utils【公共代码】
    • generate_code.sh【脚本文件】

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于JAVA+SpringBoot+Vue+uniApp小程序的心理健康测试平台
  • 真我GT 6,为什么敢叫“梦想机”?
  • Backend - C# 的日志Lognet4
  • Linux下常见压缩文件tar.xz、tar.bz2、tar.gz的区别
  • 跑GCN收敛实验时遇到的Python环境问题
  • 数学建模美赛入门
  • 科研绘图系列:R语言蜜蜂图(Beeswarm Plot)
  • 【Python大语言模型系列】Windows环境下部署Chatglm2-6B-int4大语言模型(完整教程)
  • 通用机器人里程碑!MIT提出策略组合框架PoCo,解决数据源异构难题,实现机器人多任务灵活执行
  • C# + halcon 联合编程示例
  • 图书馆数据仓库
  • 浅谈重要组件JSR223介绍
  • 打造高效的高性能计算大模型训练平台
  • vue2实现复制,粘贴功能,使用vue-clipboard2插件
  • 算术运算符用途解析及应用案例
  • Asm.js的简单介绍
  • Netty 4.1 源代码学习:线程模型
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 多线程事务回滚
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 数据可视化之 Sankey 桑基图的实现
  • 无服务器化是企业 IT 架构的未来吗?
  • 智能网联汽车信息安全
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​io --- 处理流的核心工具​
  • # 数论-逆元
  • # 透过事物看本质的能力怎么培养?
  • #DBA杂记1
  • #define用法
  • #nginx配置案例
  • (1)常见O(n^2)排序算法解析
  • (16)Reactor的测试——响应式Spring的道法术器
  • (4)事件处理——(7)简单事件(Simple events)
  • (6)设计一个TimeMap
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (十六)一篇文章学会Java的常用API
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET的微型Web框架 Nancy
  • ?.的用法
  • ??myeclipse+tomcat
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • @Query中countQuery的介绍
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法
  • [ A*实现 ] C++,矩阵地图
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [100天算法】-每个元音包含偶数次的最长子字符串(day 53)
  • [Bug]使用gradio创建应用提示AttributeError: module ‘gradio‘ has no attribute ‘inputs‘
  • [BZOJ 2142]礼物(扩展Lucas定理)
  • [BZOJ4554][TJOI2016HEOI2016]游戏(匈牙利)
  • [C++] 小游戏 斗破苍穹 2.11.6 版本 zty出品
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • [CTF夺旗赛] CTFshow Web1-12 详细过程保姆级教程~