• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

gen: GORM Gen 代码生成

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

gen

开源软件地址:

https://gitee.com/gorm/gen

开源软件介绍:

GORM/GEN

GoVersionReleaseGo.Dev referenceGo Report CardMIT licenseOpenIssueClosedIssueTODOs

基于 GORM, 更安全更友好的ORM工具。

Overview

  • 自动生成CRUD和DIY方法
  • 自动根据表结构生成model
  • 完全兼容GORM
  • 更安全、更友好
  • 多种生成代码模式

Contents

安装

安装GEN前,需要安装好GO并配置你的工作环境。

1.安装完Go(version 1.14+)之后,通过下面的命令安装gen。

go get -u gorm.io/gen

2.导入到你的工程:

import "gorm.io/gen"

快速开始

注⚠️: 这里所有的教程都是在 WithContext 模式下写的. 如果你用的是WithoutContext 模式,则可以删除所有的 WithContext(ctx) ,这样代码看起来会更简洁.

# assume the following code in generate.go file$ cat generate.go
package mainimport "gorm.io/gen"// generate codefunc main() {    // specify the output directory (default: "./query")    // ### if you want to query without context constrain, set mode gen.WithoutContext ###    g := gen.NewGenerator(gen.Config{        OutPath: "../dal/query",        /* Mode: gen.WithoutContext|gen.WithDefaultQuery*/        //if you want the nullable field generation property to be pointer type, set FieldNullable true        /* FieldNullable: true,*/        //if you want to generate index tags from database, set FieldWithIndexTag true        /* FieldWithIndexTag: true,*/        //if you want to generate type tags from database, set FieldWithTypeTag true        /* FieldWithTypeTag: true,*/        //if you need unit tests for query code, set WithUnitTest true        /* WithUnitTest: true, */    })      // reuse the database connection in Project or create a connection here    // if you want to use GenerateModel/GenerateModelAs, UseDB is necessray or it will panic    // db, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"))    g.UseDB(db)      // apply basic crud api on structs or table models which is specified by table name with function    // GenerateModel/GenerateModelAs. And generator will generate table models' code when calling Excute.    g.ApplyBasic(model.User{}, g.GenerateModel("company"), g.GenerateModelAs("people", "Person", gen.FieldIgnore("address")))        // apply diy interfaces on structs or table models    g.ApplyInterface(func(method model.Method) {}, model.User{}, g.GenerateModel("company"))    // execute the action of code generation    g.Execute()}

生成Model:

  • gen.WithoutContextWithContext 模式生成
  • gen.WithDefaultQuery 生成默认全局查询变量

项目路径

最佳实践项目模板:

demo├── cmd│   └── generate│       └── generate.go # execute it will generate codes├── dal│   ├── dal.go # create connections with database server here│   ├── model│   │   ├── method.go # DIY method interfaces│   │   └── model.go  # store struct which corresponding to the database table│   └── query  # generated code's directory|       ├── user.gen.go # generated code for user│       └── gen.go # generated code├── biz│   └── query.go # call function in dal/gorm_generated.go and query databases├── config│   └── config.go # DSN for database server├── generate.sh # a shell to execute cmd/generate├── go.mod├── go.sum└── main.go

API 示例

生成

生成Model

// generate a model struct map to table `people` in databaseg.GenerateModel("people")// generate a struct and specify struct's nameg.GenerateModelAs("people", "People")// add option to ignore fieldg.GenerateModel("people", gen.FieldIgnore("address"), gen.FieldType("id", "int64"))// generate all tables, ex: g.ApplyBasic(g.GenerateAllTable()...)g.GenerateAllTable()

字段生成 Options

FieldNew           // create new fieldFieldIgnore        // ignore fieldFieldIgnoreReg     // ignore field (match with regexp)FieldRename        // rename field in structFieldType          // specify field typeFieldTypeReg       // specify field type (match with regexp)FieldTag           // specify gorm and json tagFieldJSONTag       // specify json tagFieldGORMTag       // specify gorm tagFieldNewTag        // append new tagFieldNewTagWithNS  // specify new tag with name strategyFieldTrimPrefix    // trim column prefixFieldTrimSuffix    // trim column suffixFieldAddPrefix     // add prefix to struct member's nameFieldAddSuffix     // add suffix to struct member's nameFieldRelate        // specify relationship with other tablesFieldRelateModel   // specify relationship with exist models

类型映射

自定义数据库字段类型和go类型的映射关系.

dataMap := map[string]func(detailType string) (dataType string){  "int": func(detailType string) (dataType string) { return "int64" },  // bool mapping  "tinyint": func(detailType string) (dataType string) {    if strings.HasPrefix(detailType, "tinyint(1)") {      return "bool"    }    return "int8"  },}g.WithDataTypeMap(dataMap)

字段表达式

创建字段

实际上你需要手动创建字段,因为都会在生成代码自动创建。

Field TypeDetail TypeCreate FunctionSupported Query Method
genericfieldNewFieldIsNull/IsNotNull/Count/Eq/Neq/Gt/Gte/Lt/Lte/Like
intint/int8/.../int64NewInt/NewInt8/.../NewInt64Eq/Neq/Gt/Gte/Lt/Lte/In/NotIn/Between/NotBetween/Like/NotLike/Add/Sub/Mul/Div/Mod/FloorDiv/RightShift/LeftShift/BitXor/BitAnd/BitOr/BitFlip
uintuint/uint8/.../uint64NewUint/NewUint8/.../NewUint64same with int
floatfloat32/float64NewFloat32/NewFloat64Eq/Neq/Gt/Gte/Lt/Lte/In/NotIn/Between/NotBetween/Like/NotLike/Add/Sub/Mul/Div/FloorDiv
stringstring/[]byteNewString/NewBytesEq/Neq/Gt/Gte/Lt/Lte/Between/NotBetween/In(val/NotIn(val/Like/NotLike/Regexp/NotRegxp/FindInSet/FindInSetWith
boolboolNewBoolNot/Is/And/Or/Xor/BitXor/BitAnd/BitOr
timetime.TimeNewTimeEq/Neq/Gt/Gte/Lt/Lte/Between/NotBetween/In/NotIn/Add/Sub

创建字段示例:

import "gorm.io/gen/field"// create a new generic field map to `generic_a`a := field.NewField("table_name", "generic_a")// create a field map to `id`i := field.NewInt("user", "id")// create a field map to `address`s := field.NewString("user", "address")// create a field map to `create_time`t := field.NewTime("user", "create_time")

CRUD 接口

生成基础model userDB.

// generated code// generated code// generated codepackage queryimport "gorm.io/gen"// struct map to table `users` type user struct {    gen.DO    ID       field.Uint    Name     field.String    Age      field.Int    Address  field.Field    Birthday field.Time}// struct collectiontype DB struct {    db       *gorm.DB    User     *user}

创建

创建记录
// u refer to query.useruser := model.User{Name: "Modi", Age: 18, Birthday: time.Now()}u := query.Use(db).Usererr := u.WithContext(ctx).Create(&user) // pass pointer of data to Createerr // returns error
选择字段创建

自定义哪些字段需要插入。

u := query.Use(db).Useru.WithContext(ctx).Select(u.Name, u.Age).Create(&user)// INSERT INTO `users` (`name`,`age`) VALUES ("modi", 18)

自定义创建时需要忽略的字段。

u := query.Use(db).Useru.WithContext(ctx).Omit(u.Name, u.Age).Create(&user)// INSERT INTO `users` (`Address`, `Birthday`) VALUES ("2021-08-17 20:54:12.000", 18)
批量创建

Create 方法支持批量创建,参数只要是对应model的slice就可以. GORM会通过一条语句高效创建并返回所有的主键赋值给slice的Model.

var users = []model.User{{Name: "modi"}, {Name: "zhangqiang"}, {Name: "songyuan"}}query.Use(db).User.WithContext(ctx).Create(&users)for _, user := range users {    user.ID // 1,2,3}

CreateInBatches可以指定批量创建的大小, e.g:

var users = []User{{Name: "modi_1"}, ...., {Name: "modi_10000"}}// batch size 100query.Use(db).User.WithContext(ctx).CreateInBatches(users, 100)

也可以通过全局配置方式,在初始化gorm时设置 CreateBatchSize in gorm.Config / gorm.Session

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{    CreateBatchSize: 1000,})// ORdb = db.Session(&gorm.Session{CreateBatchSize: 1000})u := query.NewUser(db)var users = []User{{Name: "modi_1"}, ...., {Name: "modi_5000"}}u.WithContext(ctx).Create(&users)// INSERT INTO users xxx (5 batches)

查询

单个数据查询

自动生成 First, Take, Last 三个查询单条数据的方法。 执行的sql后面会自动添加 LIMIT 1 ,如果没有查到数据会返回错误: ErrRecordNotFound

u := query.Use(db).User// Get the first record ordered by primary keyuser, err := u.WithContext(ctx).First()// SELECT * FROM users ORDER BY id LIMIT 1;// Get one record, no specified orderuser, err := u.WithContext(ctx).Take()// SELECT * FROM users LIMIT 1;// Get last record, ordered by primary key descuser, err := u.WithContext(ctx).Last()// SELECT * FROM users ORDER BY id DESC LIMIT 1;// check error ErrRecordNotFounderrors.Is(err, gorm.ErrRecordNotFound)
根据主键查询数据
u := query.Use(db).Useruser, err := u.WithContext(ctx).Where(u.ID.Eq(10)).First()// SELECT * FROM users WHERE id = 10;users, err := u.WithContext(ctx).Where(u.ID.In(1,2,3)).Find()// SELECT * FROM users WHERE id IN (1,2,3);

如果是string类型的主键,比如UUID等:

user, err := u.WithContext(ctx).Where(u.ID.Eq("1b74413f-f3b8-409f-ac47-e8c062e3472a")).First()// SELECT * FROM users WHERE id = "1b74413f-f3b8-409f-ac47-e8c062e3472a";
查询所有数据
u := query.Use(db).User// Get all recordsusers, err := u.WithContext(ctx).Find()// SELECT * FROM users;
条件
基础查询
u := query.Use(db).User// Get first matched recorduser, err := u.WithContext(ctx).Where(u.Name.Eq("modi")).First()// SELECT * FROM users WHERE name = 'modi' ORDER BY id LIMIT 1;// Get all matched recordsusers, err := u.WithContext(ctx).Where(u.Name.Neq("modi")).Find()// SELECT * FROM users WHERE name <> 'modi';// INusers, err := u.WithContext(ctx).Where(u.Name.In("modi", "zhangqiang")).Find()// SELECT * FROM users WHERE name IN ('modi','zhangqiang');// LIKEusers, err := u.WithContext(ctx).Where(u.Name.Like("%modi%")).Find()// SELECT * FROM users WHERE name LIKE '%modi%';// ANDusers, err := u.WithContext(ctx).Where(u.Name.Eq("modi"), u.Age.Gte(17)).Find()// SELECT * FROM users WHERE name = 'modi' AND age >= 17;// Timeusers, err := u.WithContext(ctx).Where(u.Birthday.Gt(birthTime).Find()// SELECT * FROM users WHERE birthday > '2000-01-01 00:00:00';// BETWEENusers, err := u.WithContext(ctx).Where(u.Birthday.Between(lastWeek, today)).Find()// SELECT * FROM users WHERE birthday BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';
Not
u := query.Use(db).Useruser, err := u.WithContext(ctx).Not(u.Name.Eq("modi")).First()// SELECT * FROM users WHERE NOT name = "modi" ORDER BY id LIMIT 1;// Not Inusers, err := u.WithContext(ctx).Not(u.Name.In("modi", "zhangqiang")).Find()// SELECT * FROM users WHERE name NOT IN ("modi", "zhangqiang");// Not In slice of primary keysuser, err := u.WithContext(ctx).Not(u.ID.In(1,2,3)).First()// SELECT * FROM users WHERE id NOT IN (1,2,3) ORDER BY id LIMIT 1;
Or
u := query.Use(db).Userusers, err := u.WithContext(ctx).Where(u.Role.Eq("admin")).Or(u.Role.Eq("super_admin")).Find()// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';
Group

组合where或or 构建复杂查询

p := query.Use(db).Pizzapizzas, err := p.WithContext(ctx).Where(    p.WithContext(ctx).Where(p.Pizza.Eq("pepperoni")).        Where(p.Where(p.Size.Eq("small")).Or(p.Size.Eq("medium"))),).Or(    p.WithContext(ctx).Where(p.Pizza.Eq("hawaiian")).Where(p.Size.Eq("xlarge")),).Find()// SELECT * FROM `pizzas` WHERE (pizza = "pepperoni" AND (size = "small" OR size = "medium")) OR (pizza = "hawaiian" AND size = "xlarge")
指定字段查询

通过Select 可以选择你要查询的字段,否则就是查询所有字段。

u := query.Use(db).Userusers, err := u.WithContext(ctx).Select(u.Name, u.Age).Find
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap