GORM的另类(自动生成)用法 | 青训营

104 阅读3分钟

Hi!大家好,这是我的青训营后端分享的第三篇。本篇主要讲解大家可能已经很熟悉的GORM的一种另类,但是更加方便的用法。

相信大家在编写小型项目的时候,都是先设计数据库结构,然后再根据设计好的结构来编写逻辑代码的。当数据库结构写好之后,首先要做的就是编写代码中结构体到数据表的映射。这些代码需要与数据表的结构严格对应,是很容易出错的一段冗长代码,编写起来非常费时费力,而且很烦人。在其它语言框架中,例如Python的Django,我们可以利用Django的自动代码生成工具,通过提供数据库地址和要生成的数据表名称来自动生成这些映射代码。这样会加速项目的编写过程。那么,在Golang的GORM里有没有这样的工具,来让我们的代码生成变得自动化呢?当然有,这就是我们今天要介绍的GORM Gen工具,它可以帮助我们自动生成数据库的映射代码,甚至生成增改删查的操作。

生成数据模型

有几个方式用来生成映射结构:编写Golang代码和使用gentool工具:

编写 Go 代码

package main

import "gorm.io/gen"

func main() {
  g := gen.NewGenerator(gen.Config{
    OutPath: "../query",
    Mode: gen.WithoutContext|gen.WithDefaultQuery|gen.WithQueryInterface, // generate mode
  })

  gormdb, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"))
  g.UseDB(gormdb) // reuse your gorm db

  // Generate basic type-safe DAO API for struct `model.User` following conventions
  
  g.ApplyBasic(
  // Generate struct `User` based on table `users`
  g.GenerateModel("users"),
  
  // Generate struct `Employee` based on table `users`
 g.GenerateModelAs("users", "Employee"),


// Generate struct `User` based on table `users` and generating options
g.GenerateModel("users", gen.FieldIgnore("address"), gen.FieldType("id", "int64")),

  )
g.ApplyBasic(
// Generate structs from all tables of current database
g.GenerateAllTable()...,
)
  // Generate the code
  g.Execute()
}

这种方法可以便捷的重用代码中的GORM Database对象,并且可以方便地自定义一些生成出来的结构的属性。

使用 Gentool 工具

首先,安装 GORM Gentool

go install gorm.io/gen/tools/gentool@latest 

然后,通过命令行调用 Gentool 并传递数据库参数来生成对应的结构:

gentool -dsn "user:pwd@tcp(localhost:3306)/database?charset=utf8mb4&parseTime=True&loc=Local" -tables "orders,doctor"

gentool -c "./gen.tool"

这种方法简便快捷,适合只需要默认配置的小项目开发。

进行增改删查操作

GORM Gen的一个特点就是它不仅会为我们生成对应的结构体,还会生成简单的增改删查操作,甚至能够为我们提供的自定义SQL语句生成类型安全的代理。首先让我们看看增改删查操作:

前提

当我们想要使用 GORM 提供的增改删查语句时,必须要在 Generator 的Mode选项里传递 gen.WithDefaultQuery | gen.WithQueryInterface 这样才能为我们生成增改删查对应的接口。

增操作:

user := model.User{Name: "Modi", Age: 18, Birthday: time.Now()}

u := query.User
err := u.WithContext(ctx).Create(&user) // pass pointer of data to Create

查操作:

u := query.User

// Get the first record ordered by primary key
user, err := u.WithContext(ctx).First()

GORM 还提供了 First、Take、Last等简便方法让我们实现只取一个特定元素。

改操作:

u := query.User  // Update with conditions u.WithContext(ctx).Where(u.Activate.Is(true)).Update(u.Name, "hello")

删操作:

e := query.Email

// Email's ID is `10`
e.WithContext(ctx).Where(e.ID.Eq(10)).Delete()