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

如何通过Room/SQL查询构建复合数据类FavoriteRoute

解决方案:用Room的@Query实现Favorite到FavoriteRoute的转换

1. 调整复合数据类FavoriteRoute

由于要映射两次关联Airport表的查询结果,需要给每个Airport字段添加@Embedded并指定前缀,让Room能区分两个Airport的列:

data class FavoriteRoute(
    @Embedded(prefix = "departure_") val departure: Airport,
    @Embedded(prefix = "destination_") val destination: Airport
)

2. 在Dao中编写@Query查询语句

通过两次JOIN关联Airport表,分别匹配出发地和目的地的IATA代码,同时给查询结果的列加上对应前缀,和FavoriteRoute中的@Embedded前缀对应:

按Favorite ID查询

@Dao
interface FavoriteDao {
    @Query("""
        SELECT 
            a1.id AS departure_id,
            a1.iata_code AS departure_iata_code,
            a1.name AS departure_name,
            a1.passengers AS departure_passengers,
            a2.id AS destination_id,
            a2.iata_code AS destination_iata_code,
            a2.name AS destination_name,
            a2.passengers AS destination_passengers
        FROM favorite f
        JOIN airport a1 ON f.departure_iata_code = a1.iata_code
        JOIN airport a2 ON f.destination_iata_code = a2.iata_code
        WHERE f.id = :favoriteId
    """)
    suspend fun getFavoriteRouteById(favoriteId: Int): FavoriteRoute
}

直接通过IATA代码查询(适配传入Favorite对象的场景)

如果需要直接用传入的Favorite对象的code查询,可以使用这个方法:

@Query("""
    SELECT 
        a1.id AS departure_id,
        a1.iata_code AS departure_iata_code,
        a1.name AS departure_name,
        a1.passengers AS departure_passengers,
        a2.id AS destination_id,
        a2.iata_code AS destination_iata_code,
        a2.name AS destination_name,
        a2.passengers AS destination_passengers
    FROM airport a1, airport a2
    WHERE a1.iata_code = :departureCode 
      AND a2.iata_code = :destinationCode
""")
suspend fun getFavoriteRouteByCodes(departureCode: String, destinationCode: String): FavoriteRoute

3. 实现转换函数

基于Dao方法,实现接收Favorite参数的转换逻辑:

// 假设已通过依赖注入获取favoriteDao实例
suspend fun convertFavoriteToRoute(favorite: Favorite): FavoriteRoute {
    return favoriteDao.getFavoriteRouteByCodes(favorite.departureCode, favorite.destinationCode)
}

4. 处理Flow数据流

如果需要监听数据变化并返回Flow,只需修改Dao方法的返回类型:

@Query("""
    SELECT 
        a1.id AS departure_id,
        a1.iata_code AS departure_iata_code,
        a1.name AS departure_name,
        a1.passengers AS departure_passengers,
        a2.id AS destination_id,
        a2.iata_code AS destination_iata_code,
        a2.name AS destination_name,
        a2.passengers AS destination_passengers
    FROM favorite f
    JOIN airport a1 ON f.departure_iata_code = a1.iata_code
    JOIN airport a2 ON f.destination_iata_code = a2.iata_code
    WHERE f.id = :favoriteId
""")
fun getFavoriteRouteByIdAsFlow(favoriteId: Int): Flow<FavoriteRoute>

关于@Relation的问题说明

你之前用@Relation遇到问题,是因为@Relation默认只能基于单一外键关联同一张表,无法直接给关联表起别名来区分两次关联的场景。而直接用@Query写JOIN语句可以灵活处理这种多次关联同一张表的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:17