使用 RxJava 的 Room - 加入列表查询每个项目的数据
Room with RxJava - join list query with data of each item
我有一个 Android 应用程序,它使用 Room 和 RxJava。
假设我有两个表 box(id)
和 ball(id, color, boxId)
。
我需要一个查询 returns 所有盒子以及每种颜色的球数。
Flowable<List<BoxWithBallsCount>> getBallsWithCount();
有那个:
BoxWithBallsCount(Box box, BoxCount boxCount)
BoxCount(String ballColor, int count)
我创建了以下Dao
@Dao
public interface BoxDao {
@Query("SELECT * FROM box")
Flowable<List<Box>> getAll();
@Query("SELECT ball.color, count(*) FROM box WHERE ball.boxId = :boxId GROUP BY ball.color")
Flowable<List<BoxCount>> dificultQuery(String herdId);
}
现在我需要实现主要方法:BoxWithBallsCount
的 returns
列表可流动。
我该怎么做?
我尝试了很多RX方法,但找不到正确的方法。
谢谢
我创建了一个辅助函数来实现结果:
https://gist.github.com/mateuyabar/7f125de87788432e351d2066d94503d9#file-rxfunctions-java
package com.mateuyabar.rx;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Flowable;
/**
* Extended RX functions
* @author mateuyabar.com
*/
public class RxFunctions {
/**
* For each item on the list published by the publisher, it will map it using the mapper, and will use the merger to create the merged result.
* @return Publisher list of merged items
*/
static public <T, U, V> Flowable<List<V>> flatMapForEach(Flowable<List<T>> listPublisher, ItemMapper<T, U> mapper, Merger<T,U,V> merger){
return listPublisher.flatMap(listItem -> addData(listItem, mapper, merger));
}
static private <T, U, V> Flowable<List<V>> addData(List<T> listItem, ItemMapper<T,U> mapper, Merger<T,U,V> merger) {
if(listItem.isEmpty())
return Flowable.just(new ArrayList<>());
List<Flowable<V>> result = new ArrayList<>();
for(T item : listItem){
result.add(
mapper.subQuery(item)
.map(subQueryResult -> merger.merger(item, subQueryResult))
);
}
return Flowable.combineLatest(result, objects -> asList(objects));
}
static private <T> List<T> asList(Object[] objects) {
List<T> reuslt = new ArrayList<>();
for(Object object:objects){
reuslt.add((T) object);
}
return reuslt;
}
public interface ItemMapper<T, U>{
Flowable<U> subQuery(T item);
}
public interface Merger<T, U, V>{
V merger(T item, U subquery);
}
}
我有一个 Android 应用程序,它使用 Room 和 RxJava。
假设我有两个表 box(id)
和 ball(id, color, boxId)
。
我需要一个查询 returns 所有盒子以及每种颜色的球数。
Flowable<List<BoxWithBallsCount>> getBallsWithCount();
有那个:
BoxWithBallsCount(Box box, BoxCount boxCount)
BoxCount(String ballColor, int count)
我创建了以下Dao
@Dao
public interface BoxDao {
@Query("SELECT * FROM box")
Flowable<List<Box>> getAll();
@Query("SELECT ball.color, count(*) FROM box WHERE ball.boxId = :boxId GROUP BY ball.color")
Flowable<List<BoxCount>> dificultQuery(String herdId);
}
现在我需要实现主要方法:BoxWithBallsCount
的 returns
列表可流动。
我该怎么做?
我尝试了很多RX方法,但找不到正确的方法。
谢谢
我创建了一个辅助函数来实现结果:
https://gist.github.com/mateuyabar/7f125de87788432e351d2066d94503d9#file-rxfunctions-java
package com.mateuyabar.rx;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Flowable;
/**
* Extended RX functions
* @author mateuyabar.com
*/
public class RxFunctions {
/**
* For each item on the list published by the publisher, it will map it using the mapper, and will use the merger to create the merged result.
* @return Publisher list of merged items
*/
static public <T, U, V> Flowable<List<V>> flatMapForEach(Flowable<List<T>> listPublisher, ItemMapper<T, U> mapper, Merger<T,U,V> merger){
return listPublisher.flatMap(listItem -> addData(listItem, mapper, merger));
}
static private <T, U, V> Flowable<List<V>> addData(List<T> listItem, ItemMapper<T,U> mapper, Merger<T,U,V> merger) {
if(listItem.isEmpty())
return Flowable.just(new ArrayList<>());
List<Flowable<V>> result = new ArrayList<>();
for(T item : listItem){
result.add(
mapper.subQuery(item)
.map(subQueryResult -> merger.merger(item, subQueryResult))
);
}
return Flowable.combineLatest(result, objects -> asList(objects));
}
static private <T> List<T> asList(Object[] objects) {
List<T> reuslt = new ArrayList<>();
for(Object object:objects){
reuslt.add((T) object);
}
return reuslt;
}
public interface ItemMapper<T, U>{
Flowable<U> subQuery(T item);
}
public interface Merger<T, U, V>{
V merger(T item, U subquery);
}
}