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
相关产品推荐
相关产品推荐

