# Go使用GORM操作MySQL
GORM概述
The fantastic ORM library for Golang ,超棒的Go 语言ORM 类库
通俗的来说就是一个写好的库,使用库定义好的类实例化出的对象来操作MySQL,让对数据库的操作变得更加容易
导入包
import ( _ "github.com/go-sql-driver/mysql" //myslq驱动 "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" )
1
2
3
4
5快速开始
package main import ( _ "github.com/go-sql-driver/mysql" //myslq驱动 "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) // UserInfo 用户信息 type UserInfo struct { ID uint Name string Gender string Hobby string } func main() { db, err := gorm.Open("mysql", "root:root1234@(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local") //用户名:密码@(URL)/数据库名?charset=utf8mb4&parseTime=True&loc=Local if err!= nil{ panic(err) } defer db.Close() // 自动迁移 db.AutoMigrate(&UserInfo{}) u1 := UserInfo{1, "七米", "男", "篮球"} u2 := UserInfo{2, "沙河娜扎", "女", "足球"} // 创建记录 db.Create(&u1) db.Create(&u2) // 查询 var u = new(UserInfo) db.First(u) fmt.Printf("%#v\n", u) var uu UserInfo db.Find(&uu, "hobby=?", "足球") fmt.Printf("%#v\n", uu) // 更新 db.Model(&u).Update("hobby", "双色球") // 删除 db.Delete(&u) }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46gorm.Model
为了方便模型定义,GORM内置了一个
gorm.Model
结构体。gorm.Model
是一个包含了ID
,CreatedAt
,UpdatedAt
,DeletedAt
四个字段的Golang结构体。// gorm.Model 定义 type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time } // 将 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`字段注入到`User`模型中 type User struct { gorm.Model Name string } // 不使用gorm.Model,自行定义模型 type User struct { ID int Name string }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17模型定义示例
type User struct { gorm.Model Name string Age sql.NullInt64 Birthday *time.Time Email string `gorm:"type:varchar(100);unique_index"` Role string `gorm:"size:255"` // 设置字段大小为255 MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空 Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型 Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引 IgnoreMe int `gorm:"-"` // 忽略本字段 }
1
2
3
4
5
6
7
8
9
10
11
12结构体标记(Tag) 描述 Column 指定列名 Type 指定列数据类型 Size 指定列大小, 默认值255 PRIMARY_KEY 将列指定为主键 UNIQUE 将列指定为唯一 DEFAULT 指定列默认值 PRECISION 指定列精度 NOT NULL 将列指定为非 NULL AUTO_INCREMENT 指定列是否为自增类型 INDEX 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引 UNIQUE_INDEX 和 INDEX
类似,只不过创建的是唯一索引EMBEDDED 将结构设置为嵌入 EMBEDDED_PREFIX 设置嵌入结构的前缀 - 忽略此字段 表名
表名默认就是结构体名称的复数,例如:
type User struct {} // 默认表名是 `users` // 将 User 的表名设置为 `profiles` func (User) TableName() string { return "profiles" } func (u User) TableName() string { if u.Role == "admin" { return "admin_users" } else { return "users" } } // 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user` db.SingularTable(true)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17也可以通过
Table()
指定表名:// 使用User结构体创建名为`deleted_users`的表 db.Table("deleted_users").CreateTable(&User{}) var deleted_users []User db.Table("deleted_users").Find(&deleted_users) //// SELECT * FROM deleted_users; db.Table("deleted_users").Where("name = ?", "jinzhu").Delete() //// DELETE FROM deleted_users WHERE name = 'jinzhu';
1
2
3
4
5
6
7
8
9列名
列名由字段名称进行下划线分割来生成
type User struct { ID uint // column name is `id` Name string // column name is `name` Birthday time.Time // column name is `birthday` CreatedAt time.Time // column name is `created_at` }
1
2
3
4
5
6可以使用结构体tag指定列名:
type Animal struct { AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id` Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast` Age int64 `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast` }
1
2
3
4
5查询大法
查询单个对象
// 获取第一条记录(主键升序) db.First(&user) // SELECT * FROM users ORDER BY id LIMIT 1; // 获取一条记录,没有指定排序字段 db.Take(&user) // SELECT * FROM users LIMIT 1; // 获取最后一条记录(主键降序) db.Last(&user) // SELECT * FROM users ORDER BY id DESC LIMIT 1; result := db.First(&user) result.RowsAffected // 返回找到的记录数 result.Error // returns error or nil // 检查 ErrRecordNotFound 错误 errors.Is(result.Error, gorm.ErrRecordNotFound)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19如果你想避免
ErrRecordNotFound
错误,你可以使用Find
,比如db.Limit(1).Find(&user)
,Find
方法可以接受struct和slice的数据。查询全部对象
// 获取全部记录 result := db.Find(&users) // SELECT * FROM users; result.RowsAffected // 返回找到的记录数,相当于 `len(users)` result.Error // returns error
1
2
3
4
5
6条件查询
// 获取第一条匹配的记录 db.Where("name = ?", "jinzhu").First(&user) // SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1; // 获取全部匹配的记录 db.Where("name = ?", "jinzhu").Find(&users) // SELECT * FROM users WHERE name = 'jinzhu'; // IN db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users) // SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2'); // AND db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users) // SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22; // Time db.Where("updated_at > ?", lastWeek).Find(&users) // SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00'; // Struct db.Where(&User{Name: "jinzhu", Age: 20}).First(&user) // SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1; // Map db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users) // SELECT * FROM users WHERE name = "jinzhu" AND age = 20; // 主键切片条件 db.Where([]int64{20, 21, 22}).Find(&users) // SELECT * FROM users WHERE id IN (20, 21, 22);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31注意 当使用结构作为条件查询时,GORM 只会查询非零值字段。这意味着如果您的字段值为
0
、''
、false
或其他 零值 (opens new window),该字段不会被用于构建查询条件,例如:db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users)// SELECT * FROM users WHERE name = "jinzhu";
1当使用 struct 进行查询时,你可以通过向
Where()
传入 struct 来指定查询条件的字段、值、表名,例如:db.Where(&User{Name: "jinzhu"}, "name", "Age").Find(&users) // SELECT * FROM users WHERE name = "jinzhu" AND age = 0; db.Where(&User{Name: "jinzhu"}, "Age").Find(&users) // SELECT * FROM users WHERE age = 0;
1
2
3
4
5
增加、删除、更新以及更多的查询大法