前言
感谢开源项目gin-vue-admin,以及1010工作室的视频教程
本人学识尚浅,如有错误,请评论指出,谢谢!
详细可见个人博客:https://linzyblog.netlify.app/
一、One To One 一对一
数据库连接例子:
var db *gorm.DB
func init() {
var err error
//我这里用到数据库是mysql,需要配置DSN属性[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8&parseTime=True"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
})
if err != nil {
panic("failed to connect database")
}
}
1、Belongs To 属于
belongs to 会与另一个模型建立了一对一
的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例。
例如:你有两张表 users 表和 companies 表
- users --用户表
- companies --公司表
user 是属于 company 的,就是每个 user 有且只能对应分配给一个 company。
注意:在 User 对象中,有一个和 Company 一样的
CompanyID
。 默认情况下, CompanyID 被隐含地用来在 User 和 Company 之间创建一个外键关系
, 因此必须包含在 User 结构体中才能填充 Company 内部结构体。
// `User` 属于 `Company`,`CompanyID` 是外键
type User struct {
gorm.Model
Name string
CompanyID int // 默认情况下, CompanyID 被隐含地用来在 User 和 Company 之间创建一个外键关系
Company Company
}
type Company struct {
ID int
Name string
}
func main() {
//user 里面有 company表的结构 所以只需要自动迁移user表即可
db.AutoMigrate(&User{
})
}
1)创建记录
创建在dachang
里的用户linzy
的记录
c := Company{
ID: 1,
Name: "dachang",
}
u := User{
Name: "linzy",
Company: c,
}
db.Create(&u)
不仅 users 表新增记录,companies 表也新增了。这是因为在创建、更新记录时,GORM 会通过
Upsert
自动保存关联及其引用记录。
2)查询记录
var u User
db.Model(&User{
}).First(&u)
fmt.Println(u)
注意:我们发现并没有查出我们关联的 companies 表里面的记录,因为我们在使用CRUD的时候需要所关联的结构时,必须要使用预加载
Preload
.
var u User
db.Model(&User{
}).Preload("Company").First(&u)
fmt.Println(u)
3)重写外键
要定义一个 belongs to 关系,数据库的表中必须存在外键。默认gorm使用(关联属性类型 + 主键)组成外键名,如上面的例子User + ID 组成UserID,UserID就作为Profile的外键。
例如我们想自定义外键,就需要用标签foreignKe
来指定外键:
type User struct {
gorm.Model
Name string
CompanyRefer int
Company Company `gorm:"foreignKey:CompanyRefer"`
// 使用 CompanyRefer 作为外键
}
type Company struct {
ID int
Name string
}
4)重写引用
对于 belongs to 关系,GORM 通常使用数据库表,主表(拥有者)的主键值作为外键参考。
例如上面的例子,User 中 CompanyRefer 属性作为外键,它和Company 中的ID进行关联,这里 Company 的ID就是关联外键。
我们可以使用标签 references 来更改它,例如:
type User struct {
gorm.Model
Name string
CompanyID string
Company Company `gorm:"references:Code"` // 使用 Code 作为引用
}
type Company struct {
ID int
Code string
Name string
}
5)关联模式
a、查找关联
如果我们想查找指定的 user 匹配的关联记录,可以用Association
找users表关联的记录:
var user User
db.Where("id = ?", 1).Take(&user)
fmt.Println(user)
var c Company
// `user` 是源模型,它的主键不能为空
// 关系的字段名是 `Company`
// 如果匹配了上面两个要求,会开始关联模式,否则会返回错误
db.Model(&user).Association("Company").Find(&c)
fmt.Println(c)
b、删除关联
user 可以关联 company,同样也可以不关联,但是去库里删很麻烦,用Delete方法删除源模型与参数之间的关系,只会删除引用,不会从数据库中删除这些对象。
删除前:
var user User
db.Where("id = ?", 1).First(&user)
//一定要指定关联的主键
db.Model(&user).Association("Company").Delete(&Company{
ID: 1})
c、添加关联
var user User
db.Where("id = ?", 1).First(&user)
//一定要指定关联的主键
db.Model(&user).Association("Company").Append(&Company{
ID: 1}