Gorm主要用法| 青训营笔记

160 阅读2分钟

这是我参与「第三届青训营-后端场」笔记创作活动的第2篇笔记

Gorm基础

文档

GORM 是 Golang 的 ORM 库。官方文档现在是v2版本的文档,v1版本文档现在是一个副文档。
gorm.io/docs/
v1.gorm.io/docs/

v2版本结构

.
├── association.go
├── callbacks
│   ├── associations.go
│   ├── callbacks.go
│   ├── callmethod.go
│   ├── create.go
│   ├── delete.go
│   ├── helper.go
│   ├── interfaces.go
│   ├── preload.go
│   ├── query.go
│   ├── raw.go
│   ├── row.go
│   ├── transaction.go
│   └── update.go
├── callbacks.go
├── chainable_api.go
├── clause
│   ├── clause.go
│   ├── delete.go
│   ├── expression.go
│   ├── from.go
│   ├── group_by.go
│   ├── insert.go
│   ├── joins.go
│   ├── limit.go
│   ├── locking.go
│   ├── on_conflict.go
│   ├── order_by.go
│   ├── returning.go
│   ├── select.go
│   ├── set.go
│   ├── update.go
│   ├── values.go
│   ├── where.go
│   └── with.go
├── errors.go
├── finisher_api.go
├── gorm.go
├── interfaces.go
├── logger
│   ├── logger.go
│   ├── sql.go
├── migrator
│   └── migrator.go
├── migrator.go
├── model.go
├── prepare_stmt.go
├── scan.go
├── schema
│   ├── check.go
│   ├── field.go
│   ├── index.go
│   ├── interfaces.go
│   ├── naming.go
│   ├── relationship.go
│   ├── schema.go
│   ├── utils.go
├── soft_delete.go
├── statement.go
└── utils
    └── utils.go

验证运行用的Model

type Company struct {
    ID        int       `gorm:"primaryKey"`
    Name      string
    // Track creating/updating time/unix (milli/nano) seconds for multiple fields
    CreatedAt time.Time // Set to current time if it is zero on creating
    UpdatedAt int       // Set to current unix seconds on updating or if it is zero on creating
    Updated   int64     `gorm:"autoUpdateTime:nano"`  // Use unix Nano seconds as updating time
    Updated2  int64     `gorm:"autoUpdateTime:milli"` // Use unix Milli seconds as updating time
    Created   int64     `gorm:"autoCreateTime"`       // Use unix seconds as creating time
}

type User struct {
    ID         int `gorm:"primaryKey"`
    CompanyID  int
    Company    Company
    Name       string
    Address    string
    Age        int
    CreditCard CreditCard
    Attributes datatypes.JSON
}

type CreditCard struct {
    ID     int `gorm:"primaryKey"`
    UserID int
    Number string
}

主要功能

1.Context Support

可以用withContext传递context

var user model.User
db.WithContext(ctx).Find(&user)
// SELECT * FROM `users`

2.Batch Insert

可以批量插入SQL到database中

var users = []model.User{
    {Name: "test", Address: "address", Age: 20, CompanyID: 1},
    {Name: "test2", Address: "address2", Age: 30, CompanyID: 1},
    {Name: "test3", Address: "address3", Age: 40, CompanyID: 1},
}
db.Create(&users)
//  INSERT INTO `users` (`company_id`,`name`,`address`,`age`) VALUES (1,'test','address',20),(1,'test2','address2',30),(1,'test3','address3',40)

3.Join Preload

可以通过db.Joins("Company").Find这样进行预加载

var users []model.User
db.Joins("Company").Find(&users, "users.id IN ?", []int{1, 2})
// SELECT `users`.`id`,`users`.`company_id`,`users`.`name`,`users`.`address`,`users`.`age`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name` FROM `users` LEFT JOIN `companies` `Company` ON `users`.`company_id` = `Company`.`id` WHERE users.id IN (1,2)

4.FindInBatches

可以通过FindInBatches进行逐行处理SQL语句

var users []model.User
err := db.Where("id >= ?", 1).FindInBatches(&users, 2, func(tx *gorm.DB, batch int) error {
    for _, user := range users {
        fmt.Println(user.ID)
    }
    return nil
})
if err.Error != nil {
    fmt.Println(err.Error.Error())
}
// SELECT * FROM `users` WHERE id >= 1 LIMIT 2
// SELECT * FROM `users` WHERE id >= 1 LIMIT 2 OFFSET 2

5.SubQuery

可以编写不同类型的查询语句

// Where SubQuery
var user model.User
db.Where("age > (?)", db.Table("users").Select("AVG(age)")).Find(&user)
// SELECT * FROM `users` WHERE age > (SELECT AVG(age) FROM `users`)

// From SubQuery
db.Table("(?) as u", db.Model(&model.User{}).Select("name", "age")).Where("age = ?", 18).Find(&user)
// SELECT * FROM (SELECT `name`,`age` FROM `users`) as u WHERE age = 20

// Update SubQuery
db.Model(&model.User{}).Update(
    "age", db.Model(&model.Company{}).Select("age").Where("companies.id = users.company_id"),
)
// UPDATE `users` SET `name`=(SELECT `name` FROM `companies` WHERE companies.id = users.company_id)