这是我参与「第三届青训营-后端场」笔记创作活动的第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)