• gorm中的关联操作详解


    一对一

    belong to

    属于:可以理解为舔狗认为自己属于女神,而女神都不知道舔狗的存在
    type Girl struct { Id int Name string } type Dog struct { Id int Name string GirlId int Girl Girl } 迁移 schema db.AutoMigrate(&Dog{}) //此时会将Girl和Dog都生成

    hasone

    拥有:可以理解为女神知道舔狗的存在,舔狗只需要留一根“狗链子”在女神创建的时候交给女神就好了
    type Dog struct { Id int Name string GirlId int } type Girl struct { Id int Name string Dog Dog } //db.AutoMigrate(&Girl{}) //只有一个Girl表生成 db.AutoMigrate(&Girl{}, &Dog{}) d := Dog{Id: 1, Name: "haha0"} db.Create(&Girl{Id: 1, Name: "nv0", Dog: d}) //此时Dog中的GirlId字段被自动填写

    查询

    var girl Girl db.First(&girl, 1) fmt.Println(girl)
    直接这样查是不行的,这是需要先预加载
    改成:db.Preload("Dog").First(&girl, 1)

    关系操作

    //给舔狗创建关系
    db.Model(&Girl{Id:1}).Association("Dog").Append(&dog)
    上面是hasone的情况,belong to 的情况正好相反
    Append换为Delete,是删除连接
    换为Replace(&g1,&g2),是替换连接
    Clear(),自身去掉所有关系

    一对多

    还是上面的例子只需要微微改动
    ` type Dog struct {
    Id int
    Name string
    GirlId int
    //Girl Girl
    }

    type Girl struct {
    	Id   int
    	Name string
    	Dogs []Dog
    }
    d0 := Dog{Id: 1,
    	Name: "haha0"}
    d1 := Dog{Id: 2,
    	Name: "haha2"}
    g := &Girl{Id: 1,
    	Name: "nv0",
    	Dogs: []Dog{d0, d1},
    }
    db.Create(&g)
    db.AutoMigrate(&Girl{}, &Dog{})
    

    `
    查询:db.Preload("Dogs").First(&girl)
    还是预加载,需要如果条件判断

    • 类似内联
      `
      // 带条件的预加载 Order
      db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
      // SELECT * FROM users;
      // SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled');

    db.Where("state = ?", "active").Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
    // SELECT * FROM users WHERE state = 'active';
    // SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');

    `

    • 自定义预加载
      db.Preload("Orders", func(db *gorm.DB) *gorm.DB { return db.Order("orders.amount DESC") }).Find(&users) // SELECT * FROM users; // SELECT * FROM orders WHERE user_id IN (1,2,3,4) order by orders.amount DESC;
    • 链式预加载
      修改结构体
      type Info struct { Id int money int GogId int } type Dog struct { Id int Name string GirlId int //Girl Girl Info Info }
      注意生成数据库表的时候,各个表生成的顺序,否则报错
      db.AutoMigrate(&Girl{}, &Dog{}, &Info{})
      在查询
      db.Preload("Dogs.Info").Preload("Dogs").First(&girl)
      同时加条件的话和上面也一样,但是需要注意查询条件只适用于她所在的预加载的那一层
      例如:db.Preload("Dogs.Info", "money>100").Preload("Dogs").First(&girl)
      输出结果小于100的info信息会没有,但是dog依然会查出来,money>100条件影响不到Preload("Dogs")
      那怎么样可以实现输出结果小于100的info信息会没有,dog也没有呢,可以使用join

    join

    注意 Join适用于一对一的关系,例如: has one, belongs to
    上面的问题可以:
    db.Preload("Dogs", func(db *gorm.DB) *gorm.DB {
    return db.Joins("Info").Where("money>200")
    }).First(&girl)

    多对多

    创建格式:
    type Info struct { Id int Money int DogId int } type Girl struct { Id int Name string Dogs []Doggorm:"many2many:girl_dog"} type Dog struct { Id int Name string Girl []Girlgorm:"many2many:girl_dog" Info Info }

    查询
    1.只想查舔狗的女神有哪些,不要舔狗信息
    image
    2.舔狗信息也要,就加上预加载
    image
    想加条件和一对多差不多

    关系维护
    还是那几个函数
    image

    删除最好用事务

    最后
    image

    注意多对多情况的FK和refer和一对一/多正好相反了

    博客是观看b站up主(go圈里最会写js的奇淼)笔记
    链接:https://www.bilibili.com/video/BV1E64y1472a?p=10&spm_id_from=pageDriver&vd_source=7de631e1910751f66cb6a72edf044dab

  • 相关阅读:
    【深度优先搜索-中等】1034. 边界着色
    【let var const】
    Linux 基金会年度报告——没有人能离开 Linux 支持环境;树莓派翻新版将创建“新的”分支系统;AWS 发生中断,导致业务交付出现问题 | 开源日报
    Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)
    Impagliazzo five-worlds
    高阶数据结构[3]图的遍历
    【大作文】【图表】【第一段】
    不想当Window的Dialog不是一个好Modal,弹窗翻身记
    关于进程同步与互斥的一些概念(锁、cas、futex)
    【论文合集】2022年12月医学影像期刊论文合集
  • 原文地址:https://www.cnblogs.com/nnsy/p/16773342.html