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

如何使用Room实现组合模式(多级嵌套列表的存储与查询)

Room 多级树形嵌套查询解决方案

你目前的实现只能查询一级层级,核心原因是关联类ContentTaskEntity里的子节点列表类型是ContentEntity,本身没有携带子列表字段,只要调整类型定义即可实现自动嵌套查询,也可以用递归CTE的方案手动组装适配大数据量场景。

方案1:直接调整关联类实现自动多级查询

将ContentTaskEntity里的contentList类型从List<ContentEntity>改为List<ContentTaskEntity>即可,Room会自动递归处理每一层的关联关系,支持无限层级的树形结构查询:

data class ContentTaskEntity(
    @Embedded val content: ContentEntity,
    @Relation(
        parentColumn = "id",
        entityColumn = "parentId",
        entity = ContentEntity::class
    )
    val contentList: List<ContentTaskEntity> // 仅修改这一行的类型
)

原有Dao层的getAllContentTask()方法不需要任何修改,直接调用就能返回完整的多级嵌套结构。
该方案优势是代码改动极小,不需要手动处理数据组装,适合层级不超过3层、单表数据量小于1000条的场景。

方案2:递归CTE+手动组装适配大数据量场景

如果数据层级深、数据量大,Room自动递归查询会产生多次数据库IO,性能更低,可以用SQLite的递归CTE先一次性查询出所有关联节点,再手动组装成树形结构:

第一步:新增递归查询Dao方法

@Query("""
    WITH RECURSIVE content_tree(id, name, type, parentId) AS (
        -- 查根节点
        SELECT id, name, type, parentId FROM content WHERE parentId = :rootParentId
        UNION ALL
        -- 递归查所有子节点
        SELECT c.id, c.name, c.type, c.parentId 
        FROM content c 
        INNER JOIN content_tree ct ON c.parentId = ct.id
    )
    SELECT * FROM content_tree
""")
fun getWholeContentTree(rootParentId: Int = -1): List<ContentEntity>

第二步:手动组装树形结构

fun assembleContentTree(flatNodeList: List<ContentEntity>): List<ContentTaskEntity> {
    // 存储id对应节点的映射
    val nodeMap = flatNodeList.associate { 
        it.id to ContentTaskEntity(content = it, contentList = mutableListOf()) 
    }
    val rootNodes = mutableListOf<ContentTaskEntity>()
    
    flatNodeList.forEach { node ->
        if (node.parentId == -1) {
            rootNodes.add(nodeMap[node.id]!!)
        } else {
            (nodeMap[node.parentId]?.contentList as? MutableList<ContentTaskEntity>)?.add(nodeMap[node.id]!!)
        }
    }
    return rootNodes
}

调用方式

@Transaction
fun getCompleteContentTree(): List<ContentTaskEntity> {
    val flatList = getWholeContentTree()
    return assembleContentTree(flatList)
}

该方案仅需要一次数据库IO,性能远高于自动递归查询,适合层级深、数据量大的场景,也支持自定义组装规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:24:00