基于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【腳本文件】

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43166.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43166.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43166.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ClickHouse表引擎概述

ClickHouse表引擎概述 表引擎的功能&#xff1a; 數據的存儲方式 數據的存儲位置 是否可以使用索引 是否可以使用分區 是否支持數據副本 并發數據訪問 ClickHouse在建表時必須指定表引擎。 表引擎主要分為四大類&#xff1a;MergeTree系列、Log系列、與其他存儲/處理系…

字節碼編程bytebuddy之獲取方法信息和方法入參信息

寫在前面 本文看下通過bytebuddy如何獲取方法信息和方法的入參信息。 1&#xff1a;代碼 package com.dahuyou.bytebuddy.bb;import com.dahuyou.bytebuddy.TT; import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.implement…

【高中數學/對數函數】比較a=ln2/2,b=ln5/5的大小

【問題】 比較aln2/2,bln5/5的大小 【解答】 a-bln2/2-ln5/5(5*ln2-2*ln5)/10(ln2^5-ln5^2)/10(ln32-ln25)/10>0 所以a>b 【圖像】 如果繪出函數ylnx/x的圖像&#xff0c;再標記出a,b的位置&#xff0c;則繪出圖像如下&#xff1a; 由上圖可以看出&#xff0c;a,b兩…

隨手記:對比兩個對象不一樣的值,生成一個新的對象

diffObject(obj1, obj2) {let changeForm {}for (let key in obj1) {if (!obj1.hasOwnProperty(key) || obj1[key] ! obj2[key]) {// 新舊數據不相同的key值changeForm[key] obj1[key]}}console.log(changeForm, changeForm)},

初次用bable遍歷vue項目下的中文

利用 babel 找到 AST 中的中文 // vite-plugin-babel-transform.js const parser require(babel/parser) const traverse require(babel/traverse).default // const types require(babel/types) // const generate require(babel/generator).default const fs require(f…

【PHP小課堂】學習PHP中的字符串操作函數(二)

學習PHP中的字符串操作函數&#xff08;二&#xff09; 接下來我們繼續 PHP 中字符串函數的學習。今天學習的內容主要是帶下劃線的一些字符串函數&#xff0c;上篇文章說過&#xff0c;這些系統函數的命名是 PHP 非常令人詬病的&#xff0c;有些東西真的只能靠我們的記憶來強行…

顯卡、顯卡驅動、cuda、cuDNN之間關系

顯卡、顯卡驅動、CUDA 和 cuDNN 是構成高性能計算和深度學習環境的關鍵組件&#xff0c;它們之間有著緊密的聯系。下面是對這些組件及其關系的詳細介紹&#xff1a; 顯卡&#xff08;GPU&#xff09; 顯卡&#xff0c;全稱為圖形處理器&#xff08;Graphics Processing Unit&…

【Unity2D 2022:NPC】制作任務系統

一、接受任務 1. 編輯NPC對話腳本&#xff1a; &#xff08;1&#xff09;創建靜態布爾變量用來判斷ruby是否接受到任務 public class NPCDialog : MonoBehaviour {// 創建全局變量用來判斷ruby是否接到任務public static bool receiveTask false; } &#xff08;2&#xff…

python學習-錯誤與異常

代碼是人的邏輯思維的具體體現&#xff0c;因為沒有一個人的邏輯思維是完美無缺的&#xff0c;所以人在編寫代碼時必然會出現各種錯誤。既然錯誤或多或少都會發生&#xff0c;那么如何捕捉錯誤&#xff0c;并且捕捉到錯誤后要如何處理&#xff0c;就顯得很重要。 語法錯誤 Py…

SPI通信協議和W25Q64

前言&#xff1a; STM32中的通信接口&#xff1a; UART 單總線 IIC SPI CAN 1. SPI FLASH W25Q64的關系 SPI:一種通信接口&#xff0c;可以用于和搭載SPI接口的設備通信 FLASH:是一種掉電不丟失的存儲 -- 手機8256G的256 單片機 64K512K的512 芯片內部flash&…

STM32 GPIO的工作原理

STM32的GPIO管腳有下面8種可能的配置:&#xff08;4輸入 2 輸出 2 復用輸出) &#xff08;1&#xff09;浮空輸入_IN_FLOATING 在上圖上&#xff0c;陰影的部分處于不工作狀態&#xff0c;尤其是下半部分的輸出電路&#xff0c;實際上是與端口處于隔離狀態。黃色的高亮部分顯示…

響應式布局下關于gird柵格布局的一些構思

1、傳列數&#xff0c;根據列數計算元素容器寬度 好處是子元素可以寫百分比寬度&#xff0c;不用固定某一種寬度&#xff0c;反正知道列數通過計算間距就能得到外層容器的寬度。 舉個簡單的例子&#xff1a; &#xff08;ps:以下用例皆在html中去模擬&#xff0c;就不另外起r…

Python 獲取 SQL 指紋和 HASH 值

前言 本文介紹一個提取 SQL 指紋的方法&#xff0c;就是將 SQL 語句的條件轉換為 &#xff1f;可用于脫敏和 SQL 聚類分析的場景。 1. 工具安裝 這里用到的工具&#xff0c;就是 pt 工具集中的 pt-fingerprint 含在 Percona Toolkit 中&#xff0c;安裝方法可參考 Percona T…

python7:裝飾器

目錄 1.調用外部程序os.system-阻塞式調用subprocess-python中的模塊 2.裝飾器前戲作用域&#xff08;1&#xff09;全局和局部-就近原則&#xff08;2&#xff09;嵌套作用域&#xff08;3&#xff09;內置作用域、變量 高階函數&#xff1a;函數是最高級的對象&#xff08;1&…

海外媒體投稿:5個軟文代發經典案例,教大家獲得突破

隨著互聯網的飛速發展&#xff0c;軟文代發成為一種高效的推廣方法。下面我們就詳細介紹五個成功軟文代發推廣實例&#xff0c;致力于幫助讀者把握有關方法&#xff0c;完成突破。 第一實例&#xff1a;社交網絡散播在如今社交媒體時代&#xff0c;軟文代發能夠通過社交平臺迅速…

nodejs實現:支付寶訂單查詢

nodejs實現&#xff1a;支付寶訂單查詢&#xff1b; 原生http請求&#xff0c;不使用三方庫&#xff1b; 代碼如下&#xff1a; const https require(https); const crypto require(crypto); const querystring require(querystring);// 支付寶公共參數 const PRIVATE_KE…

[C++] 輕熟類和對象

類的定義 格式規范 class為定義類的關鍵字&#xff0c;后有類名&#xff0c;類的主體存于{}中&#xff1b;類定義結束時后面的分號不能省略&#xff1b;類體的內容成為類的成員&#xff0c;類中的變量成為成員變量&#xff0c;函數成為方法或成員函數&#xff1b;C兼容C語言的…

微軟 Edge 瀏覽器全解析

微軟 Edge 是微軟推出的一個現代化瀏覽器,繼承了 Internet Explorer(IE)的部分功能,但在速度、安全性和兼容性方面做出了很大改進。下面是對微軟 Edge 瀏覽器的詳細解析,包括其特點、安裝、配置和常見問題的解答。 微軟 Edge 瀏覽器的特點 基于 Chromium 內核 Edge 瀏覽…

SpringBoot配置flyway

背景 目前我們的項目代碼都會交由Git、SVN等版本管理工具進行管理&#xff0c;但是我們的sql腳本&#xff0c;尤其是各類ddl腳本并沒有進行版本的管理&#xff08;python的web框架Django默認就提供了類似的工具&#xff0c;從一開始就鼓勵開發者通過版本管理的方式進行數據庫的…

C++中的多重繼承和虛繼承:橫向繼承、縱向繼承和聯合繼承;虛繼承

多重繼承 A.橫向多重繼承&#xff1a; B.縱向多重繼承&#xff1a; C.聯合多重繼承&#xff1a; 因為 single 和 waiter 都繼承了一個 worker 組件&#xff0c;因此 SingingWaiter 將包含兩個 worker 組件&#xff0c;那么將派生類對象的地址賦給基類指針將出現二義性 那么如何…