zoukankan      html  css  js  c++  java
  • 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增删改查

     
  • 相关阅读:
    电脑知识
    编译器错误信息: CS0433: 类型“ASP.global_asax”同时存在于“c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727...的解决方法
    windows平台下的oracle ORA-01031的解决方法
    .NET下使用HTTP请求的正确姿势
    EasyUI Datagrid 分页
    Js 运算符(加减乘除)
    Navicat 运行 Oracle 存储过程示例
    oracle数据库忘记sys(或system)账户密码
    SQL Server 死锁问题
    C# 给某个方法设定执行超时时间
  • 原文地址:https://www.cnblogs.com/chadiandianwenrou/p/14030775.html
Copyright © 2011-2022 走看看