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
相关产品推荐
相关产品推荐

