gorm-gen文档
官方文档 https://gorm.io/zh_CN/gen/ 传统gorm的通点 这是gorm的查询语句 var user models.UserModel global.DB.Take(&
gorm-gen文档
发布时间:2025-04-11 (2025-04-11)

官方文档

https://gorm.io/zh_CN/gen/

传统gorm的通点

这是gorm的查询语句

var user models.UserModel
global.DB.Take(&user, "username = ?", "fengfeng")

相信大家在写gorm查询语句的时候,心里肯定就在想,字段名称直接写死在代码里面,到时候这个字段改名了怎么办?

对,会报错,而且是在运行时报错

如果能在编译时就发现这个问题并解决,这样就不至于将问题推到运行时

并且gorm的create,where等方法,参数接收的都是any类型,但是如果错传类型,也是要在运行时才能知道错误

如果使用gen,上面这些烦恼都可以解决

通过表生成模型

如果是现有表,再写代码,可以使用这种方法

先模拟建个表

-- 创建用户表
CREATE TABLE users (
   id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
   name VARCHAR(50) NOT NULL COMMENT '用户名',
   age INT NOT NULL COMMENT '年龄',
   addr VARCHAR(100) NOT NULL COMMENT '地址',
   createdAt DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';

-- 创建视频表
CREATE TABLE videos(
    id        INT AUTO_INCREMENT PRIMARY KEY COMMENT '视频ID',
    user_id   INT          NOT NULL COMMENT '用户ID(关联用户表)',
    title     VARCHAR(100) NOT NULL COMMENT '视频标题',
    src       VARCHAR(255) NOT NULL COMMENT '视频地址',
    createdAt DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    -- 添加外键约束
    FOREIGN KEY (user_id) REFERENCES users (id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频信息表';

通过GenerateAllTable生成gorm模型,再通过ApplyBasic生成代码

package main

import (
  "fmt"
  "gen_study/models"
  "gorm.io/driver/mysql"
  "gorm.io/gen"
  "gorm.io/gorm"
)

func main() {
  g := gen.NewGenerator(gen.Config{
    OutPath:       "./query",                                     // gen代码的输出目录
    ModelPkgPath:  "models",                                      // 模型代码的输出目录
    Mode:          gen.WithDefaultQuery | gen.WithoutContext, // 启用默认查询和链式接口
    FieldNullable: true,                                          // 允许 NULL 的字段生成指针类型
  })

  dia := mysql.Open("root:root@tcp(127.0.0.1:3306)/gen_study?charset=utf8mb4&parseTime=True&loc=Local")
  db, err := gorm.Open(dia, &gorm.Config{})
  if err != nil {
    fmt.Println(err)
    return
  }
  g.UseDB(db)
  g.GenerateAllTable()        // 通过sql表生成gorm模型
  g.Execute()                 // 执行
}

GenerateAllTable是生成这个库下所有表的

也可以指定表生成模型代码

g.GenerateModel("users")

这种方式生成的,是不带外键信息的

生成外键模型

配置要稍微复杂一些

// 生成视频模型并关联用户
videoModel := g.GenerateModel("videos",
  gen.FieldRelate(field.BelongsTo, "User",
    g.GenerateModel("users"),
    &field.RelateConfig{
      GORMTag: field.GormTag{
        "foreignKey": []string{"UserID"},
      },
    }),
)

// 生成用户模型并关联视频
g.GenerateModel("users",
  gen.FieldRelate(field.HasMany, "Videos",
    videoModel,
    &field.RelateConfig{
      GORMTag: field.GormTag{
        "foreignKey": []string{"UserID"},
      },
    }),
)

通过模型生成gen代码

有了模型之后,就可以通过模型生成gen代码

g.ApplyBasic(models.User{}, models.Video{})

增删改查操作

有了生成的gen代码

对于增删改查操作会非常简单

创建记录

创建单条

query.SetDefault(db)

user := models.User{
  Name: "枫枫",
  Age:  21,
  Addr: "cs",
}
err := query.User.Create(&user)
fmt.Println(user, err)

创建多条

u1 := models.User{
  Name: "枫枫",
  Age:  21,
  Addr: "cs",
}
u2 := models.User{
  Name: "zhangsan",
  Age:  22,
  Addr: "cs",
}
var userList = []*models.User{&u1, &u2}
err := query.User.Create(userList...)
fmt.Println(u1, u2, err)

查询语句

// 查全部
users, _ := query.User.Find()
for _, user := range users {
  fmt.Println(user)
}

// 带条件查询
user, _ := query.User.Where(query.User.Name.Eq("zhangsan")).Take()
fmt.Println(user)

// 外键查询  用户关联的视频列表
videos, _ := query.User.Videos.Model(&models.User{ID: 1}).Find()
for _, video := range videos {
  fmt.Println(video)
}

更新

// 更新单列  必须要有where
res, err := query.User.Where(query.User.ID.Eq(1)).Update(query.User.Name, "fengfeng")
fmt.Println(res, err)

// 更新多列 只能更新非零值
res, err = query.User.Where(query.User.ID.Gte(1)).Updates(models.User{
  Name: "zhangsan",
})

删除

// 根据主键删除
res, err := query.User.Where(query.User.ID.Eq(1)).Delete()
fmt.Println(res, err)

// 根据model删除
res, err = query.User.Delete(&models.User{ID: 2})
fmt.Println(res, err)