Go语言学习之Grom一对多关系

创建表结构

package main

import (
    "fmt"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

type User struct {
    gorm.Model
    Name string
    CreditCards []CreditCard `gorm:"foreignKey:UserID"`    //UserID就是外键的名称,因为一对多关系下,外键是写在[多]的那个表结构里
}

type CreditCard struct {
    gorm.Model
    Number    string
    UserID    uint    //这个就是外键
}


func main() {

var db *gorm.DB
    var err error
    db, err = gorm.Open("mysql", "root:xxxx@tcp(127.0.0.1:62249)/prom?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
        fmt.Println("1123")
        fmt.Println(err)
    }
if db.HasTable(&User{}) { db.AutoMigrate(&User{}) } else { db.CreateTable(&User{}) } db.AutoMigrate(&CreditCard{}) }

他们之间的关系就是一个用户 可以有 多张卡,所以是一对多关系

填充表数据

User表数据

 

CreditCard表数据

 

 

 

 

实现一对多的查询有两种办法

第一种是Preload

func main(){

    var user []User  //设置接收的切片,因为这个可以获取user表里的所有数据,所以需要切片接收数据
    db.Find(&user)  //获取user表里所有数据
    fmt.Println(user)  //打印此时的user数据,是user表的所有数据
    //根据user表去获取CreditCard表的数据
    db.Model(&user).Preload("CreditCards").Find(&user)
    fmt.Println(user) //打印此时的user数据,是包含user表的数据和creditcard表的数据的
    //循环user数据,这一层循环能获取到user表的所有字段信息
    for _,b := range user {
        fmt.Println(b.Name)
        //根据user字段的信息去获取CreditCard表所有字段的信息
        for _,i := range b.CreditCards{
            fmt.Println(i.Number,b.Name)
        }
    }
}
##########################结果##########################

[{{1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} junming []} {{2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} taotao []}]


[{{1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} junming [{{1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 123456 1} {{2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 654321 1}]} {{2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} taotao [{{3 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 1111111 2} {{4 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 2222222 2}]}]


junming
123456 junming
654321 junming

taotao
1111111 taotao
2222222 taotao


第二种是Related

    var user User  //Related只能获取一条数据,所以不需要用切片接收
    db.Find(&user)  //只能获取user表的最后一条数据,赋值给user
    fmt.Println(user)
    //根据user表的信息,去获取CreditCard表的数据,由于只获取到的一条user表的信息,所以只能获取这条user表信息对应的CreditCard表的信息,赋值给user
db.Model(&user).Related(&user.CreditCards,"CreditCard").Find(&user)
    fmt.Println(user)
    fmt.Println(user.CreditCards)
    //根据这个user表的信息去获取对应CreditCard的所有字段
    for _,i := range user.CreditCards {
        fmt.Println(i.Number)
    }
##############3结果##############
{{2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} taotao []}
{{
2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} taotao [{{3 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 1111111 2} {{4 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 2222222 2}]}
[{{
3 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 1111111 2} {{4 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} 2222222 2}]

1111111 2222222

Proload和Related的区别

总结:如果需要查出所有关联的数据就用Preload,查一条关联数据用Related

借鉴如下

https://www.jianshu.com/p/a36aa0679a12   

Gorm一对多关系踩坑

http://gorm.book.jasperxu.com/crud.html#q

GORM 中文文档

https://www.jianshu.com/p/1513f55f8192

Go组件学习——gorm四步带你搞定DB增删改查

 

 

 

posted @ 2020-11-24 16:01  差点点温柔  阅读(1259)  评论(0编辑  收藏  举报