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

如何借助Hilt与ViewModel从RoomDB获取Sale及关联SaleProducts?

最优实现方案:Room关联查询+一次性监听

核心思路是利用Room的@Relation注解直接查询出包含关联SaleProducts的Sale数据,彻底避免多次查询和多观察者管理的麻烦。

1. 创建组合数据类封装关联数据

定义一个专门的组合类,用来打包Sale及其对应的所有关联产品:

data class SaleWithProducts(
    @Embedded val sale: Sale,
    @Relation(
        parentColumn = "sale_id", // Sale表的主键字段名
        entityColumn = "sale_id"  // SaleProducts表中关联Sale的外键字段名
    )
    val products: List<SaleProduct>
)
  • @Embedded:将Sale实体的字段直接嵌入这个组合类中
  • @Relation:指定一对多的关联规则,Room会自动完成关联数据的查询和匹配

2. 在Dao中添加关联查询方法

修改你的SaleDao,新增带事务的关联查询方法:

@Dao
interface SaleDao {
    // 新增关联查询,必须加@Transaction保证原子性
    @Transaction
    @Query("SELECT * FROM Sale")
    fun getSalesWithAllProducts(): LiveData<List<SaleWithProducts>>
}

@Transaction是必须的,确保多表查询的原子性,避免出现Sale和Products数据不一致的情况。

3. 仓库层暴露关联数据

在仓库类中注入SaleDao,并对外提供关联数据的LiveData:

class SaleRepository @Inject constructor(
    private val saleDao: SaleDao
) {
    fun getSalesWithProducts(): LiveData<List<SaleWithProducts>> {
        return saleDao.getSalesWithAllProducts()
    }
}

4. ViewModel中获取关联数据

通过Hilt注入仓库,直接拿到包含关联数据的LiveData:

@HiltViewModel
class SaleViewModel @Inject constructor(
    private val saleRepository: SaleRepository
) : ViewModel() {
    val salesWithProducts: LiveData<List<SaleWithProducts>> = saleRepository.getSalesWithProducts()
}

5. UI层一次性监听数据

在Activity/Fragment中只需要监听这一个LiveData,无需循环处理每个Sale的单独查询:

// Activity/Fragment中
viewModel.salesWithProducts.observe(viewLifecycleOwner) { saleWithProductsList ->
    saleWithProductsList.forEach { item ->
        val targetSale = item.sale
        val relatedProducts = item.products
        // 直接处理业务逻辑
    }
}

方案优势

  • 性能更优:从N+1次查询(1次查所有Sale+N次查对应Products)简化为1次查询,减少数据库IO开销
  • 逻辑简洁:仅需管理一个观察者,避免多LiveData监听的复杂度
  • 数据一致:通过事务保证关联查询的原子性,避免数据不同步问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:22:07