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

RxJava2配合Room使用时如何传入id数组实现批量数据查询

实现步骤

1. DAO层新增批量查询方法(完全不影响原有单查逻辑)

在你的UserDao中新增接收id数组/集合的查询方法,Room原生支持SQL的IN关键字匹配集合参数,原有getById方法无需任何修改:

// 原有单查方法保留不动
@Query("SELECT * FROM user WHERE id = :id")
fun getById(id: String): Observable<UserEntity>

// 新增批量查询方法
@Query("SELECT * FROM user WHERE id IN (:ids)")
fun getByIds(ids: Array<String>): Observable<List<UserEntity>>

如果需要返回结果的顺序和传入id数组的顺序一致,可以修改SQL为:

@Query("SELECT * FROM user WHERE id IN (:ids) ORDER BY CASE id WHEN :ids[0] THEN 0 WHEN :ids[1] THEN 1 ... ELSE 9999 END")
fun getByIds(ids: Array<String>): Observable<List<UserEntity>>

2. 上层调用适配(可复用原有逻辑,无需修改现有单查请求)

你可以在Provider层新增重载方法,同时兼容单个id和id数组的入参,原有单查的调用链路完全不用改动:

  • 入参为单个id时走原有getById逻辑
  • 入参为数组时走新增的getByIds逻辑

批量查询的RxJava调用逻辑和原有结构高度对齐,仅需要把单对象转换改为列表转换即可,还可以抽离转换逻辑复用:

// 抽离复用的转换逻辑
private fun convertToInfoStruct(entity: UserEntity): InfoStruct {
    return InfoStruct(
        entity.Name.toString(),
        entity.Id.toString()
    )
}

// 原有单查逻辑完全不变
userDatabase.userDao().getById(id)
    .subscribeOn(Schedulers.io())
    .observeOn(SchedulerProvider.ui())
    .map { convertToInfoStruct(it) }
    .subscribe(
        { println("${it.userName} || ${it.userId}") },
        { println("Error") }
    )

// 新增批量查询逻辑,结构和单查对齐
val idArray = arrayOf("id1", "id2", "id3")
userDatabase.userDao().getByIds(idArray)
    .subscribeOn(Schedulers.io())
    .observeOn(SchedulerProvider.ui())
    .map { entityList -> entityList.map { convertToInfoStruct(it) } }
    .subscribe(
        { infoList -> infoList.forEach { println("${it.userName} || ${it.userId}") } },
        { println("Error") }
    )

可选优化:如果不能修改DAO层代码

如果由于封装限制无法新增DAO方法,可以用RxJava的concatMapEager操作符批量发起单查请求,性能比手动写for循环更高,且请求可以并行执行:

val idList = listOf("id1", "id2", "id3")
Observable.fromIterable(idList)
    .concatMapEager { id -> 
        userDatabase.userDao().getById(id)
            .subscribeOn(Schedulers.io())
    }
    .map { convertToInfoStruct(it) }
    .toList()
    .observeOn(SchedulerProvider.ui())
    .subscribe(
        { infoList -> infoList.forEach { println("${it.userName} || ${it.userId}") } },
        { println("Error") }
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 01:15:10