Golang Generate DB CRUD

背景

一般的業(yè)務(wù)開發(fā)經(jīng)常需要設(shè)計(jì)表結(jié)構(gòu),然后一系列的增刪改查等。為了能夠稍微減少這些重復(fù)勞動,寫了一個簡單的腳本自動生成表結(jié)構(gòu)信息。

依賴

項(xiàng)目介紹

Github 地址 https://github.com/vnotes/gendb

├── go.mod
├── go.sum
├── main.go
├── model
│   ├── db2.tmpl
│   ├── db.tmpl
│   ├── format.go
│   ├── tablesapi
│   │   └── TABLES_gen.go
│   ├── TABLES_gen.go
│   └── template.go
├── mysqldb
│   ├── mysql.go
│   ├── table.go
│   └── table_info.go
└── README.md
  • mysqldb 是 MySQL 的數(shù)據(jù)庫連接信息
  • model 是 CRUD 模板。提供了 2 個:db 和 db2
  • model/TABLES_gen.go model/tablesapi/TABLES_gen.go 是 2 個模板的例子。

效果

CREATE TABLE `sale_order` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `order_name` varchar(32) NOT NULL DEFAULT '' COMMENT '訂單號',
  `order_line` bigint NOT NULL DEFAULT '0' COMMENT '訂單行',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `state` tinyint NOT NULL DEFAULT '0' COMMENT '訂單狀態(tài)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_order_line` (`order_line`),
  UNIQUE KEY `uk_order_name` (`order_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='銷售訂單信息';

target=sale_order type=2 go run main.go -u root -h 127.0.0.1 -p root -d dev

  • target是目標(biāo)數(shù)據(jù)庫表
  • type為2是用模板2.
  • 其他的就是數(shù)據(jù)庫信息了。

生成

// Code generated by gendb; DO NOT EDIT.

package saleorderapi

import (
    "context"
    "database/sql"
    "fmt"
    "strings"
    "time"

    "github.com/jmoiron/sqlx"
)

const TableName = "sale_order"

type column struct {
    CreateTime string
    Id         string
    OrderLine  string
    OrderName  string
    State      string
    UpdateTime string
}

var (
    Col = &column{
        CreateTime: "create_time",
        Id:         "id",
        OrderLine:  "order_line",
        OrderName:  "order_name",
        State:      "state",
        UpdateTime: "update_time",
    }
)

type Entity struct {
    CreateTime time.Time `db:"create_time"` // 創(chuàng)建時間
    Id         int64     `db:"id"`          // 自增主鍵
    OrderLine  int64     `db:"order_line"`  // 訂單行
    OrderName  string    `db:"order_name"`  // 訂單號
    State      int8      `db:"state"`       // 訂單狀態(tài)
    UpdateTime time.Time `db:"update_time"` // 更新時間
}

type model interface {
    dbInsert(context.Context, ...map[string]interface{}) (sql.Result, error)
    dbSelect(context.Context, map[string]interface{}, ...string) ([]*Entity, error)
}

type impl struct {
    db sqlx.ExtContext
}

var i *impl

func SetCli(db sqlx.ExtContext) {
    i = &impl{db: db}
}

func GetCli() model {
    return i
}

var _ model = (*impl)(nil)

func (i *impl) dbInsert(ctx context.Context, values ...map[string]interface{}) (sql.Result, error) {
    if len(values) == 0 {
        return nil, nil
    }
    var fields []string
    for k := range values[0] {
        fields = append(fields, k)
    }
    k := strings.Join(fields, ",")
    v := ":" + strings.Join(fields, ",:")
    s := fmt.Sprintf("INSERT INTO sale_order (%s) VALUES (%s);", k, v)
    result, err := sqlx.NamedExecContext(ctx, i.db, s, values)
    if err != nil {
        return nil, fmt.Errorf("insert error %w", err)
    }
    return result, nil
}

func (i *impl) dbSelect(ctx context.Context, values map[string]interface{}, fields ...string) ([]*Entity, error) {
    var result []*Entity

    var s []string
    var args []interface{}
    for k, v := range values {
        s = append(s, fmt.Sprintf("%s=?", k))
        args = append(args, v)
    }
    var query = fmt.Sprintf("SELECT %s FROM sale_order WHERE %s", strings.Join(fields, ","), strings.Join(s, " and "))
    err := sqlx.SelectContext(ctx, i.db, &result, query, args...)
    if err != nil {
        return nil, fmt.Errorf("select error %w", err)
    }
    return result, nil
}

簡書如何折疊代碼??

個人疑惑:

對于上述生成的代碼,如何使用就看個人。個人習(xí)慣的開發(fā)模式為
model目錄下的二級目錄是表的增刪改查和表相關(guān)的信息。因?yàn)槟夸洷旧韼в?namespace 的概念,因此很多變量省去了表這個主體,例如 Col,Cli 等。而不是 saleOrderCol 這些。
然后同級別是 external,外部依賴等等。
就看目前結(jié)構(gòu)看個人開發(fā)習(xí)慣和公司規(guī)定,統(tǒng)一就 Okay
至于 Cli 如何初始化就看自己的寫法了....

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容