GORM关联查询问题:按VersionCode筛选Package及关联Version数据
GORM关联查询按VersionCode筛选Package问题解决
模型定义
type Packages struct { ID uint `json:"id" gorm:"primary_key"` PackageName string `json:"package_name" gorm:"type:varchar(100)"` Version []Version `json:"version" gorm:"foreignkey:PackageID;constraint:OnDelete:CASCADE;"` } type Version struct { ID uint `json:"id" gorm:"primary_key"` CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` PackageID uint `json:"-"` VersionCode string `json:"version_code" gorm:"type:varchar(100);uniqueIndex:idx_uniq"` BuildNumber int `json:"build_number"` }
你需要按VersionCode筛选出包含对应关联Version完整信息的Package数据,原生SQL能正常返回结果,但原GORM写法用了LEFT JOIN,导致返回全部Package——这是因为LEFT JOIN会保留左表(packages)的所有记录,哪怕没有匹配的version数据,不符合条件的Package也会被返回。
下面提供两种可行的解决方案:
方案1:改用INNER JOIN
把LEFT JOIN替换成JOIN(GORM中JOIN等价于INNER JOIN),仅返回有匹配Version记录的Package:
var packages []Packages // 方式一:条件放在WHERE子句 config.DB.Select("*").Joins("JOIN versions ON packages.id=versions.package_id").Where("versions.version_code=?", version_code).Find(&packages) // 方式二:条件放在JOIN的ON子句,效果一致 config.DB.Select("*").Joins("JOIN versions ON packages.id=versions.package_id AND versions.version_code=?", version_code).Find(&packages)
方案2:使用GORM预加载+存在性筛选
利用模型已定义的关联关系,用Preload加载符合条件的Version数据,同时通过EXISTS子句过滤无匹配的Package,更符合ORM使用习惯:
var packages []Packages config.DB.Preload("Version", "version_code=?", version_code). Where("EXISTS (SELECT 1 FROM versions WHERE versions.package_id = packages.id AND versions.version_code=?)", version_code). Find(&packages)
这里Preload负责将符合条件的Version数据填充到Package的Version字段,Where中的EXISTS确保只返回包含目标VersionCode的Package。
内容的提问来源于stack exchange,提问作者raj
相关产品推荐
相关产品推荐

