如何将两个不同API的返回结果保存至同一张Room数据库表
两个不同API返回结果存入同一张Room表实现方法
核心思路是做一层数据模型转换,不要直接把API返回的原始数据类作为Room实体,通过统一实体+来源标记+映射转换的方式实现单表存储,完全不需要依赖双表+MergeAdapter的方案。
第一步:定义通用Room实体类
抽离两个API返回数据的公共字段作为表的通用列,新增sourceType整数字段标记数据来源,两个接口独有的字段全部声明为可空类型,避免非空约束报错。另外主键必须拼接来源前缀,防止两个API返回的条目ID重复导致数据被覆盖。@Entity(tableName = "common_content") data class CommonContentEntity( @PrimaryKey val uniqueId: String, // 两个接口共有的业务字段 val title: String, val cover: String, val publishTime: Long, // 来源标记:1=第一个API 2=第二个API val sourceFrom: Int, // 第一个API独有字段,设默认null val api1ExclusiveLabel: String? = null, // 第二个API独有字段,设默认null val api2ExclusiveViewCount: Long? = null )第二步:编写API模型到Room实体的转换逻辑
分别给两个API的返回数据类写扩展转换函数,在转换阶段完成字段名映射、主键拼接、来源标记赋值,把不同结构的接口数据统一转成上面的通用实体格式:// 第一个API返回条目转通用实体 fun Api1Item.toCommonEntity(): CommonContentEntity { return CommonContentEntity( uniqueId = "api1_${this.itemId}", // 拼前缀避免主键冲突 title = this.rawTitle, cover = this.coverUrl, publishTime = this.createTimestamp, sourceFrom = 1, api1ExclusiveLabel = this.tag ) } // 第二个API返回条目转通用实体 fun Api2Item.toCommonEntity(): CommonContentEntity { return CommonContentEntity( uniqueId = "api2_${this.id}", title = this.contentTitle, cover = this.picUrl, publishTime = this.publishTime, sourceFrom = 2, api2ExclusiveViewCount = this.viewNum ) }第三步:DAO层与数据层逻辑实现
DAO只需要针对通用实体写插入、查询方法即可,插入冲突策略根据业务选择,一般同ID数据覆盖更新选REPLACE即可:@Dao interface ContentDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun batchInsertContent(dataList: List<CommonContentEntity>) // 全量查询直接返回所有数据,按发布时间倒序 @Query("SELECT * FROM common_content ORDER BY publishTime DESC") fun loadAllContent(): Flow<List<CommonContentEntity>> }仓库层发起两个API请求拿到结果后,分别调用对应的转换函数转成通用实体列表,合并后直接调用DAO的插入方法即可。UI层直接观察
loadAllContent()返回的数据,提交给单个RecyclerView Adapter就能实现统一展示,不需要用MergeAdapter。
注意:实体类不需要保留两个API返回的所有字段,只保留实际业务会用到的字段即可,无用字段在转换阶段直接丢弃,减少数据库存储空间占用。
内容的提问来源于stack exchange,提问作者yusufgltc
相关产品推荐
相关产品推荐

