You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GORM如何获取递归关联的全部层级Children字段值

GORM 递归查询全层级分类解决方案

GORM 默认的Preload方法仅会加载直接关联的第一层子资源,要获取全层级的递归分类,可选用以下两种成熟方案:


方案1:动态递归预加载(适配任意层级)

通过自定义预加载回调函数实现无限层级递归加载,无需提前知道最大层级:

// 递归预加载回调
func preloadChildren(db *gorm.DB) *gorm.DB {
    return db.Preload("Children", preloadChildren)
}

// 查询示例:默认查询所有顶级分类并加载全量子分类
var categories []Category
err := DB.Scopes(preloadChildren).Where("parent_id IS NULL").Find(&categories).Error
if err != nil {
    // 自行处理查询错误
}

原理:每一层的Children关联都会复用同一个递归预加载函数,直到对应层级没有子分类时自动停止查询。


方案2:固定层级预加载(适配层级已知场景)

如果业务中分类的最大层级是固定的,比如最多3级,可以直接链式写全层级预加载路径,写法更简单:

var categories []Category
// 示例适配最大4级分类:顶级→1级→2级→3级
err := DB.Preload("Children.Children.Children.Children").Where("parent_id IS NULL").Find(&categories).Error

注意:如果实际分类层级超过你指定的预加载层数,超出部分的子分类不会被加载。


大数据量优化方案

如果分类数据量级较大,以上两种方案会产生N+1查询问题,建议直接使用数据库递归CTE查询,性能提升明显,PostgreSQL示例如下:

var categories []Category
err := DB.Raw(`
WITH RECURSIVE category_tree AS (
    -- 递归起点:所有顶级分类
    SELECT id, name, parent_id FROM categories WHERE parent_id IS NULL
    UNION ALL
    -- 递归逻辑:关联查询所有子分类
    SELECT c.id, c.name, c.parent_id FROM categories c
    INNER JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree ORDER BY parent_id, id
`).Scan(&categories).Error
// 查询得到扁平化的全量分类后,可自行遍历组装为树形结构

内容的提问来源于stack exchange,提问作者Saifullah Shahen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:18:03