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

Android Room多表查询:如何定义含List<Street>的响应POJO类?

解决Room无法识别List字段的问题

这个问题我之前也碰到过!Room默认没法直接把游标里的多条街道数据自动组装成List<Street>,因为你的查询返回的是扁平的行结构(每个城市+单条街道占一行),而Room不知道怎么把这些行合并成嵌套的列表对象。别担心,用Room的@Embedded和@Relation注解就能完美解决,具体步骤如下:

1. 确保实体类的关联关系正确

首先要保证City和Street实体类定义了正确的关联外键,这样Room才能明确两张表的关联逻辑:

@Entity(tableName = "cities")
data class City(
    @PrimaryKey val id: Int,
    val name: String
)

@Entity(
    tableName = "streets",
    foreignKeys = [ForeignKey(
        entity = City::class,
        parentColumns = ["id"],
        childColumns = ["city_id"],
        onDelete = ForeignKey.CASCADE // 可选,用于保证数据一致性
    )]
)
data class Street(
    @PrimaryKey val id: Int,
    val name: String,
    val city_id: Int // 关联City表的主键id
)

2. 修改CityResponse数据类

用@Embedded标注City对象,告诉Room这是要嵌入的主实体;再用@Relation标注List<Street>,指定两张表的关联字段:

data class CityResponse(
    @Embedded val city: City,
    @Relation(
        parentColumn = "id",    // City表的主键字段
        entityColumn = "city_id" // Street表中关联City的外键字段
    )
    val streets: List<Street>
)

3. 编写DAO层的查询方法

需要加上@Transaction注解,保证查询城市和关联街道的操作在同一个事务中执行,避免数据不一致:

@Dao
interface CityDao {
    // 查询所有城市及其关联街道
    @Transaction
    @Query("SELECT * FROM cities")
    fun getAllCitiesWithStreets(): List<CityResponse>

    // 查询单个城市及其关联街道
    @Transaction
    @Query("SELECT * FROM cities WHERE id = :cityId")
    fun getCityWithStreets(cityId: Int): CityResponse?
}

为什么之前的写法不行?

你原来的查询返回的是扁平的结果行(比如1 City1 1 Street1是一行,1 City1 2 Street2是另一行),Room无法自动识别这些行属于同一个城市,也就没法把它们合并成包含List<Street>的对象。而@Relation注解会告诉Room:“先获取所有City实体,然后为每个City去Street表中查询对应的关联数据,再把这些Street组装成List放到CityResponse里”,@Transaction则确保整个过程是原子性的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:35:32