再探-利用gorm自身提供的方法实现MySQL中数据关联的能力
文章发布较早,内容可能过时,阅读注意甄别。
之前在使用 gorm 对接 MySQL 的时候,关联的方案使用的是自己维护的外键方式,最近重新接触 gorm,发现其内部支持关联的更好实现,这里整理记录一下。
代码内容如下:
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var db *gorm.DB
// User 用户模型
type User struct {
gorm.Model
UserName string `gorm:"type:varchar(128)" json:"userName"` // 用户名
NickName string `gorm:"type:varchar(128)" json:"nickName"` // 昵称
}
// Group 分组
type Group struct {
gorm.Model
GroupName string `json:"groupName" gorm:"type:varchar(128);"` //部门名称
Users []*User `gorm:"many2many:group_users" json:"users"`
}
// InitDB 初始化DB
func InitDB() {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&collation=%s&%s",
"root",
"123465",
"localhost",
3306,
"test-gorm",
"utf8mb4",
"utf8mb4_general_ci",
"parseTime=true",
)
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
// 禁用外键(指定外键时不会在mysql创建真实的外键约束)
DisableForeignKeyConstraintWhenMigrating: true,
//// 指定表前缀
//NamingStrategy: schema.NamingStrategy{
// TablePrefix: config.Conf.Mysql.TablePrefix + "_",
//},
})
if err != nil {
panic(fmt.Errorf("初始化mysql数据库异常: %v", err))
}
// 2, 把模型与数据库中的表对应起来
dbAutoMigrate()
}
// 自动迁移表结构
func dbAutoMigrate() {
db.AutoMigrate(
&User{},
&Group{},
)
}
func main() {
// 1,初始化
InitDB()
// 2,创建测试数据
CreateUser()
CreateGroup()
// 新增关联
AddRelation()
// 查询关联
SelectRelation()
// 替换关联
ReplaceRelation()
// 清空关联
ClearRelation()
// 删除关联
RemoveRelation()
// 计数关联
CountRelation()
}
func SelectRelation() {
var data Group
id := 1
err := db.Debug().Where("id = ?", id).Preload("Users").Find(&data).Error
if err != nil {
fmt.Printf("err: %v\n", err)
}
for _, users := range data.Users {
fmt.Println(users)
}
}
func AddRelation() {
var group Group
var users []User
ids := []int{1, 2}
err := db.Where("id IN (?)", ids).Find(&users).Error // 查询ID为1和2的用户
if err != nil {
fmt.Printf("err: %v\n", err)
}
db.First(&group, 1)
// 将刚刚查询到的用户添加到分组中
db.Model(&group).Association("Users").Append(users)
}
func ReplaceRelation() {
var group Group
var users []User
// 全量替换关联
ids1 := []int{3, 4}
err1 := db.Where("id IN (?)", ids1).Find(&users).Error // 查询ID为1和2的用户
if err1 != nil {
fmt.Printf("err: %v\n", err1)
}
db.Model(&group).Association("Users").Replace(users) // 全量替换关联
}
func ClearRelation() {
var group Group
db.First(&group, 1)
db.Model(&group).Association("Users").Clear()
}
func RemoveRelation() {
var group Group
var users []User
ids1 := []int{1, 2}
err1 := public.DB.Where("id IN (?)", ids1).Find(&users).Error // 查询ID为1和2的用户
if err1 != nil {
fmt.Printf("err: %v\n", err1)
}
// 先查询到将要解除关联的group
err := public.DB.First(&group, 1).Error
if err != nil {
fmt.Printf("get group data failed:%v\n", err)
}
err = public.DB.Model(&group).Association("Users").Delete(users)
if err != nil {
fmt.Printf("delete relation failed:%v\n", err)
}
}
func CountRelation() {
// 关联计数
var group Group
db.First(&group, 1)
i := db.Model(&group).Association("Users").Count()
fmt.Printf("i: %v\n", i)
}
// CreateUser 创建用户
func CreateUser() {
User1 := &User{UserName: "eryajf1", NickName: "二丫讲梵1"}
User2 := &User{UserName: "eryajf2", NickName: "二丫讲梵2"}
User3 := &User{UserName: "eryajf3", NickName: "二丫讲梵3"}
User4 := &User{UserName: "eryajf4", NickName: "二丫讲梵4"}
User5 := &User{UserName: "eryajf5", NickName: "二丫讲梵5"}
db.Debug().Model(&User{}).Create(&User1)
db.Debug().Model(&User{}).Create(&User2)
db.Debug().Model(&User{}).Create(&User3)
db.Debug().Model(&User{}).Create(&User4)
db.Debug().Model(&User{}).Create(&User5)
}
func CreateGroup() {
g1 := &Group{GroupName: "ops"}
g2 := &Group{GroupName: "test"}
db.Debug().Model(&Group{}).Create(&g1)
db.Debug().Model(&Group{}).Create(&g2)
}
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
上次更新: 2024/11/19, 23:11:42