gorm关联详解
2019-02-19 本文已影响17人
林子老公
学习gorm时,感觉文档中的related相关内容比较模糊,没有一个完整的实例.看了源码之后,才把整个原理搞清楚.
先看数据结构:
gorm-related.pngdemo代码如下:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
type User struct {
ID uint `gorm:"primary_key"`
Birthday string `gorm:"column:birthday"`
Age int `gorm:"column:age"`
Name string `gorm:"column:name"`
BillingAddress Address `gorm:"foreignkey:BillingAddressId;"` // One-To-One (属于 - 本表的BillingAddressID作外键
BillingAddressId int `gorm:"column:billing_address_id"`
ShippingAddress Address `gorm:"foreignkey:ShippingAddressId;"` // One-To-One (属于 - 本表的ShippingAddressID作外键)
ShippingAddressId int `gorm:"column:shipping_address_id"`
CreditCard CreditCard `gorm:"foreignkey:UserID;"` // One-To-One (拥有一个 - CreditCard表的UserID作外键)
Emails []Email `gorm:"ForeignKey:UserID;"` // One-To-Many (拥有多个 - Email表的UserID作外键)
Languages []Language `gorm:"many2many:user_languages;"` // Many-To-Many , 'user_languages'是连接表
}
type Email struct {
ID int `gorm:"primary_key"`
UserID int `gorm:"column:user_id;"` // 外键 (属于), tag `index`是为该列创建索引
Email string `gorm:"column:email"` // `type`设置sql类型, `unique_index` 为该列设置唯一索引
}
type Address struct {
ID int `gorm:"primary_key"`
Address1 string `gorm:"column:address1"` // 设置字段为非空并唯一
Address2 string `gorm:"column:address2"`
Post string `gorm:"column:post"`
}
type Language struct {
ID int `gorm:"primary_key"`
Name string `gorm:"column:name"` // 创建索引并命名,如果找到其他相同名称的索引则创建组合索引
Code string `gorm:"column:code"` // `unique_index` also works
}
type CreditCard struct {
ID int `gorm:"primary_key"`
UserID int `gorm:"column:user_id;"`
Number string `gorm:"column:number"`
}
func main() {
url := fmt.Sprintf("%s:%s@(%s)/%s?charset=utf8&parseTime=True&loc=Local", "root", "123456", "localhost:3306", "demo")
db, err := gorm.Open("mysql", url)
db.LogMode(true)
if err != nil {
panic("failed to connect database")
}
db.DB().SetMaxIdleConns(30)
db.DB().SetMaxOpenConns(60)
defer db.Close()
defer func() {
if e := recover(); e != nil {
fmt.Println(e)
}
}()
t1 := time.Now()
u := User{ID: 1}
db.Model(&u).Find(&u)
db.Model(&u).Related(&u.CreditCard,"CreditCard")
db.Model(&u).Related(&u.Emails,"Emails")
db.Model(&u).Related(&u.Languages, "Languages")
db.Model(&u).Related(&u.BillingAddress,"BillingAddress")
db.Model(&u).Related(&u.ShippingAddress,"ShippingAddress")
fmt.Println(u)
t2 := time.Now()
fmt.Println("gorm耗时:", t2.Sub(t1))
}
func (u User) TableName() string {
return "user"
}
func (u Email) TableName() string {
return "email"
}
func (u Address) TableName() string {
return "address"
}
func (u Language) TableName() string {
return "language"
}
func (u CreditCard) TableName() string {
return "creditcard"
}
运行结果:
{1 1999-10-01 20 张三 {2 武汉市汉阳区 武汉市关山大道 4300000} 2 {1 武汉市洪山区 武汉市关山大道 4300000} 1 {11 1 xxxx-11111} [{1 1 11@11.com} {2 1 22@11.com}] [{1 汉语 ch} {2 英语 en}]}
说明都关联对象都查出来了.
总结:
belongs_to,has_one主要是用于1对1的关系.has_many用于1对多关系,many_to_many用于多对多.
感觉gorm最大的优势就是能级联查询,但是就是例子太少,官方文档也太简略.