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

Android Room操作ExpRecord时不修改实体类获取分类名称的方法

Android Room 多表关联查询方案(无需在ExpRecord中添加冗余字段)

你不需要修改现有ExpRecord实体的字段定义,直接使用Room提供的关联查询注解即可实现需求,具体实现步骤如下:

  • 定义关联查询组合数据类
    新建普通数据类,通过@Embedded嵌入主表ExpRecord的字段,再通过@Relation注解配置和另外两张表的关联关系,Room会自动完成关联字段的映射。因为你配置了外键删除规则为SET_NULL,关联的分类、货币实体要声明为可空类型,避免关联数据被删除后查询崩溃:
    data class RecordWithExtendInfo(
        @Embedded val record: ExpRecord,
        @Relation(
            parentColumn = "expCategoryID",
            entityColumn = "id"
        )
        val category: ExpCategory?,
        @Relation(
            parentColumn = "currencyID",
            entityColumn = "id"
        )
        val currency: Currency?
    )
    
  • 在DAO层编写关联查询方法
    给查询方法加上@Transaction注解保证多表查询的原子性,直接返回上述组合数据类的类型即可,Room会自动完成多表关联查询逻辑,不需要手写JOIN语句:
    @Dao
    interface ExpRecordDao {
        @Transaction
        @Query("SELECT * FROM Record")
        fun getAllRecords(): Flow<List<RecordWithExtendInfo>>
    
        @Transaction
        @Query("SELECT * FROM Record WHERE date BETWEEN :startDate AND :endDate")
        fun getRecordsByDateRange(startDate: String, endDate: String): Flow<List<RecordWithExtendInfo>>
    }
    
  • 在ViewModel、Adapter中直接访问关联字段
    ViewModel层直接从DAO层收集返回的Flow/LiveData数据即可,不需要额外做数据转换;Adapter绑定时直接读取对应字段:
    • 消费记录本身的金额、日期、备注:通过item.record.amount、item.record.date、item.record.note访问
    • 分类名称:通过item.category?.name ?: "未分类"访问,加空值兜底适配分类被删除的场景
    • 货币符号:通过item.currency?.symbol ?: "¥"访问,同样做空值适配处理

方案优势

  • 无冗余字段:不需要在ExpRecord表中额外存储分类名、货币符号,不会出现多表数据不一致的问题
  • 自动映射:Room编译期自动生成关联查询代码,不需要手写字段映射逻辑,类型安全
  • 实时同步:分类、货币表的信息更新后,查询消费记录时关联信息会自动同步,不需要额外更新Record表数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:16:06