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

Android Room实现多层嵌套关联查询及批量删除方法问询

一、完善嵌套关联实体类

Room支持嵌套@Relation处理多层级父子关联,你需要逐层定义包含子列表的实体类,最终组装完整层级结构:

1. 定义C关联D的实体

data class CWithDs(
    @Embedded val c: C,
    @Relation(
        parentColumn = "_id",
        entityColumn = "parent_id",
        entity = D::class
    )
    val listD: List<D>
)

2. 定义B关联CWithDs的实体

data class BWithCs(
    @Embedded val b: B,
    @Relation(
        parentColumn = "_id",
        entityColumn = "parent_id",
        entity = C::class
    )
    val listC: List<CWithDs>
)

3. 最终的FullEntity(A关联BWithCs)

替换你原有的FullEntity,用嵌套关联实体实现完整层级:

data class FullEntity(
    @Embedded val a: A,
    @Relation(
        parentColumn = "_id",
        entityColumn = "parent_id",
        entity = B::class
    )
    val listB: List<BWithCs>
)
二、实现关联数据查询

无需手动编写复杂多表LEFT JOIN,Room会自动处理嵌套@Relation的查询逻辑,只需在DAO中添加带@Transaction的查询方法(保证原子性):

@Dao
interface FullDao {
    @Transaction
    @Query("SELECT * FROM a WHERE _id = :aId")
    suspend fun getFullEntityById(aId: Long): FullEntity?
}
三、批量删除关联数据

提供两种实现方式,优先推荐外键级联删除:

方式一:外键级联删除(推荐)

在各子表实体类中配置外键,设置onDelete = ForeignKey.CASCADE,删除A时会自动递归删除所有关联的B、C、D:

B表实体配置外键

@Entity(
    tableName = "b",
    foreignKeys = [
        ForeignKey(
            entity = A::class,
            parentColumns = ["_id"],
            childColumns = ["parent_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class B(
    @PrimaryKey(autoGenerate = true) val _id: Long,
    val parent_id: Long
)

C表实体配置外键

@Entity(
    tableName = "c",
    foreignKeys = [
        ForeignKey(
            entity = B::class,
            parentColumns = ["_id"],
            childColumns = ["parent_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class C(
    @PrimaryKey(autoGenerate = true) val _id: Long,
    val parent_id: Long
)

D表实体配置外键

@Entity(
    tableName = "d",
    foreignKeys = [
        ForeignKey(
            entity = C::class,
            parentColumns = ["_id"],
            childColumns = ["parent_id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class D(
    @PrimaryKey(autoGenerate = true) val _id: Long,
    val parent_id: Long
)

DAO中删除方法

只需删除A,级联操作自动处理所有关联数据:

@Dao
interface FullDao {
    // ... 其他方法
    @Query("DELETE FROM a WHERE _id = :aId")
    suspend fun deleteAAndRelated(aId: Long)
}

方式二:手动分层删除(无外键时使用)

若无法使用外键,需按从底层到顶层的顺序删除,并用@Transaction保证所有删除操作原子性:

@Dao
interface FullDao {
    // ... 其他方法
    @Transaction
    suspend fun deleteAllRelated(aId: Long) {
        deleteDsByAId(aId)
        deleteCsByAId(aId)
        deleteBsByAId(aId)
        deleteA(aId)
    }

    @Query("DELETE FROM d WHERE parent_id IN (SELECT _id FROM c WHERE parent_id IN (SELECT _id FROM b WHERE parent_id = :aId))")
    suspend fun deleteDsByAId(aId: Long)

    @Query("DELETE FROM c WHERE parent_id IN (SELECT _id FROM b WHERE parent_id = :aId)")
    suspend fun deleteCsByAId(aId: Long)

    @Query("DELETE FROM b WHERE parent_id = :aId")
    suspend fun deleteBsByAId(aId: Long)

    @Query("DELETE FROM a WHERE _id = :aId")
    suspend fun deleteA(aId: Long)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:34:49