栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

gorm Preload主子表查询 学习笔记

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gorm Preload主子表查询 学习笔记

主表字段中有一个子表的集合,子表存主表的关联id,类似于这样的结构:

//主表
type User struct{
    ID       int
    Info []UserInfo //子表的数据
}

//子表
type UserInfo struct{
    ID      int
    UserId  int //主表的id
}

我之前不太会,都是两个表分别查,然后在拼接在一起,相当的麻烦

然后大佬给了个方法,查sql的时候用一下 Preload ,直接就出来了

//主表
type User struct{
    ID       int
    Info []UserInfo  `gorm:"foreignKey:UserId;"`
}

func(User) TableName()string{
    return "user"  //数据库对应的表名
}

//子表
type UserInfo struct{
    ID      int
    UserId  int
}

user := make([]*User,0)
err := global.GVA_DB.Preload("Info").Find(&user).Error
//Preload 里面的字段是Info,不是UserInfo

会生成两条SQL语句

SELECt * FROM `user_info` WHERe `user_info`.`user_id` IN (1,2,3,4) AND `user_info`.`deleted_at` IS NULL

 SELECT * FROM `user` WHERe `user`.`deleted_at` IS NULL

学艺不精啊,虽然好像看过sql的预加载,但是完全想不起来用。不愧是大佬啊,感谢升哥

 -------------------------------------------------------------------------------------------------------

今天又用到了这个,想写一个能连接三张表的Proload, 但是总是不对,怎么也查不出来,改成两个表的还是不行,只是告诉我 :unsupported relations,我来来回回看了好几遍gorm文档,也没看出来有啥问题,网上搜索也没找到怎么解决。。。然后看了我之前的代码,唯一的区别就是,写的时候没有加model。。。

//这个是之前的成功的
	var customer []model.CustomerPack
	err   = global.GVA_DB.Where("id = ?",id).Preload("DistributePack").Find(&customer).Error


//然后是这个
    var stowage []*response.StowageAreaGoods2
	err = global.GVA_DB.Model(&model.stowage).Preload("CustomerPack").Preload("CustomerPack.DistributePack").Find(&stowage).Error

按照我之前的理解,db.model() 的作用就是确定表名,生成sql后的from ‘表名’ 就是model里面的结构体的tableName方法确定的。因为单查询生成的sql语句 和preload查询的sql完全一样,所以导致我完全搞不懂那里有错误,为何Preload是不支持的关系。

  最后实验发现,加Model( ) 也可以,只是model里面的结构体必须和上面定义的相同,类似于:

	var stowage []*response.StowageAreaGoods2
	err = global.GVA_DB.Model(&response.StowageAreaGoods2{}).Preload("CustomerPack").Preload("CustomerPack.DistributePack").Find(&stowage).Error

那么db.model() 的作用也就明了了,确定各个结构体之间的关系,确定整体的结构,只是之前的查询都是单查询或者直接查视图,没有认识到model()的作用。

        这样查出来的数据是三级的树形结构,同时需要在第二级按照其中一个“sequence”字段进行排序;如果直接加上 .Order() 方法是对第一级的stowage表排序,所以需要用到一个骚操作:

gorm实现多对多映射,以及预加载排序 - 简书

	err = global.GVA_DB.
    Preload("CustomerPack", func(db *gorm.DB) *gorm.DB{
		return db.Order("sequence")
	}).Preload("CustomerPack.DistributePack").Find(&stowage).Error

还可以这么写,不过第二种sql查询好像更加耗时

	err = global.GVA_DB.
    Preload("CustomerPack", func(db *gorm.DB) *gorm.DB{
		return db.Order("sequence").Preload("DistributePack")
	}).Find(&stowage).Error

生成的sql 

 二级的数据
SELECt * FROM `v_customer_pack` WHERe `v_customer_pack`.`stowage_id` IN (1,2,3) AND `v_customer_pack`.`deleted_at` IS NULL ORDER BY sequence

三级的数据
SELECT * FROM `distribute_pack` WHERe `distribute_pack`.`customer_id` IN (3,1) AND `distribute_pack`.`deleted_at` IS NULL

一级的数据
SELECT * FROM `stowage` WHERe `stowage`.`deleted_at` IS NULL

--------------------------------------------------------------------

Preload References 的用法

有种情况是 主子表不是通过主表id关联的

主表 
type BackWarehouse struct {
	ID          uint   `json:"id"`
	BackNumber  string `json:"backNumber" `
	BackType    string `json:"backType" `
	BackStatus  string `json:"backStatus" `
	CustomerId  uint   `json:"customerId" `
	TransportId uint   `json:"transportId" `
	OrderId     uint   `json:"orderId" `
}

子表
type OrderDetail struct {
	ID           uint   `json:"id"`
	OrderId      int    `json:"orderId" `
	ProductId    int    `json:"productId" `
	ProductCount int    `json:"productCount"`
	BackCount    uint   `json:"backCount" `
	ProductCode  string `json:"productCode"`
}

现在要用 OrderId 关联两个表
type BackOrder struct {
	BackWarehouse
	OrderDetail []*OrderDetail `json:"order" gorm:"foreignKey:OrderId;references:OrderId"`
}                                                                        

references 的作用就是确定用哪个字段链接,但是也不能没有foreignKey,没有就会报错 :

invalid field found for struct com-psms-server/model.BackOrder's field OrderDetail, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface

无法识别`OrderDetail` 字段 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/945423.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号