一对多的添加有两种情况:
- 一种是添加用户的时候同时创建文章
- 其次是创建文章关联已经存在的用户。
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// User 用户表 一个用户拥有多篇文章
type User struct {
ID int64
Name string `gorm:"size:6"`
Articles []Article //用户拥有的文章列表 has many
}
type Article struct {
ID int64 `gorm:"size:4"`
Title string `gorm:"size:16"`
UserID int64 //属于 belongs to
}
func (*User) TableName() string {
return "user"
}
func (*Article) TableName() string {
return "article"
}
func main() {
dsn := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
db.Debug().AutoMigrate(&User{}, &Article{})
var u User
a1 := Article{
Title: "redis",
}
u = User{
Name: "yanzi",
Articles: []Article{
{
Title: "golang",
},
{
Title: "k8s",
},
a1,
},
}
db.Debug().Create(&u)
}
[8.981ms] [rows:3] INSERT INTO `article` (`title`,`user_id`) VALUES ('golang',2),('k8s',2),('redis',2) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user
_id`)
[14.812ms] [rows:1] INSERT INTO `user` (`name`) VALUES ('yanzi')
最后一种就是关联已有用户
var articles []Article
articles = []Article{
{
Title: "cherry",
UserID: 2,
},
{
Title: "marry",
UserID: 2,
},
}
db.Debug().Create(&articles)
[11.754ms] [rows:2] INSERT INTO `article` (`title`,`user_id`) VALUES ('cherry',2),('marry',2)
外键添加
var u User
db.Debug().Take(&u, 3)
var a Article
db.Debug().Take(&a, 7)
u.Articles = []Article{a}
db.Debug().Save(&u)
[1.300ms] [rows:1] SELECT * FROM `user` WHERE `user`.`id` = 3 LIMIT 1
[1.629ms] [rows:1] SELECT * FROM `article` WHERE `article`.`id` = 7 LIMIT 1
[2.901ms] [rows:2] INSERT INTO `article` (`title`,`user_id`,`id`) VALUES ('marry',3,7) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
[6.363ms] [rows:0] UPDATE `user` SET `name`='test' WHERE `id` = 3
[0.557ms] [rows:0] INSERT INTO `article` (`title`,`user_id`,`id`) VALUES ('marry',3,7) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
[3.713ms] [rows:0] INSERT INTO `user` (`name`,`id`) VALUES ('test',3) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`)
mysql> select * from user;
+----+-------+
| id | name |
+----+-------+
| 1 | lucas |
| 2 | yanzi |
| 3 | test |
+----+-------+
mysql> select * from article;
+----+--------+---------+
| id | title | user_id |
+----+--------+---------+
| 1 | golang | 1 |
| 2 | k8s | 1 |
| 3 | golang | 2 |
| 4 | k8s | 2 |
| 5 | redis | 2 |
| 6 | cherry | 2 |
| 7 | marry | 3 |
+----+--------+---------+
var u User
db.Debug().Take(&u, 3)
var a Article
db.Debug().Take(&a, 6)
db.Debug().Model(&u).Association("Articles").Append(&a)
[2.196ms] [rows:2] INSERT INTO `article` (`title`,`user_id`,`id`) VALUES ('cherry',3,6) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)
model是声明映射关系的对象类型,通过这个对象类型,找到表名和字段。
var u User
db.Debug().Take(&u, 3)
var a Article
db.Debug().Take(&a, 5)
db.Debug().Model(&u).Association("Articles").Append(&a)
[1.409ms] [rows:1] SELECT * FROM `user` WHERE `user`.`id` = 3 LIMIT 1
[1.254ms] [rows:1] SELECT * FROM `article` WHERE `article`.`id` = 5 LIMIT 1
[2.285ms] [rows:2] INSERT INTO `article` (`title`,`user_id`,`id`) VALUES ('redis',3,5) ON DUPLICATE KEY UPDATE `user_id`=VALUES(`user_id`)