这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
1、Gorm介绍
ORM框架
官方文档: GORM Guides | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
2、Gorm下载
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
3、快速开始
导入模块
package main
import (
"gorm.io/gorm"
"gorm.io/driver/mysql"
)
声明Gorm Model(定义表的字段)
可以这样声明(不常用)
type Product struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Code string
Price uint
}
GORM更喜欢约定而不是配置。默认情况下,使用GORM作为主键,将结构名复数化为表名和列名,并使用来跟踪创建/更新
gorm.Model GORM定义了一个结构体
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"` }
可以将其嵌入到结构体中以包含这些字段
type Product struct {
gorm.Model
Code string
Price uint
}
连接数据库
func main() {
db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/world?charset=utf8"),
&gorm.Config{})
if err != nil {
panic("failed to connect database")
}
mysql.Open打开数据库
root:123456@tcp(127.0.0.1:3306)/world?charset=utf8
连接名:密码@tcp(地址:端口号)/数据库名?配置信息
自动迁移 Auto Migration
自动迁移schema,以使schema保持最新。 注意:AutoMigrate将创建表、缺少外键、约束、列和索引。如果现有列的大小、精度和可为空值发生变化,它将更改现有列的类型。它不会删除未使用的列来保护数据。
// Migrate the schema
db.AutoMigrate(&Product{})
db.AutoMigrate(&User{}, &Product{}, &Order{})
创建记录
// Create
db.Create(&Product{Code: "D42", Price: 100})
要高效地插入大量记录,请将切片传递给Create方法。GORM将生成一个SQL语句来插入所有数据和回填主键值,也将调用hook方法
var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}}
db.Create(&users)
GORM提供First、Take、Last方法从数据库中检索单个对象,在查询数据库时添加LIMIT 1条件,如果没有找到记录,则返回错误ErrRecordNotFound。
// Read
var product Product
db.First(&product, 1) // find product with integer primary key
db.First(&product, "code = ?", "D42") // find product with code D42
// Get the first record ordered by primary key
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;
// Get one record, no specified order
db.Take(&user)
// SELECT * FROM users LIMIT 1;
// Get last record, ordered by primary key desc
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
result := db.First(&user)
result.RowsAffected
// returns count of records found
result.Error
// returns error or nil
// check error ErrRecordNotFound
errors.Is(result.Error, gorm.ErrRecordNotFound)
如果要避免ErrRecordNotFound错误,可以像db.Limit(1).Find(&user)一样使用Find。Find方法同时接受结构和切片数据
First和Last方法将按主键顺序分别查找第一条和最后一条记录。只有当指向目标结构的指针作为参数传递给方法时,或者当使用db.model()指定模型时,它们才有效。此外,如果没有为相关模型定义主键,则模型将按第一个字段排序。例如:
var user User
var users []User
// works because destination struct is passed in
db.First(&user)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// works because model is specified using `db.Model()`
result := map[string]interface{}{}
db.Model(&User{}).First(&result)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1
// doesn't work
result := map[string]interface{}{}
db.Table("users").First(&result)
// works with Take
result := map[string]interface{}{}
db.Table("users").Take(&result)
// no primary key defined, results will be ordered by first field (i.e., `Code`)
type Language struct {
Code string
Name string
}
db.First(&Language{})
// SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1