官方文档
传统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)