【问题标题】:Room with RxJava - join list query with data of each itemRoom with RxJava - 使用每个项目的数据加入列表查询
【发布时间】:2020-01-15 12:21:40
【问题描述】:

我有一个使用 Room 和 RxJava 的 Android 应用。

假设我有两个表box(id)ball(id, color, boxId)。 我需要一个查询来返回所有包含每种颜色的球数的框。

Flowable<List<BoxWithBallsCount>> getBallsWithCount();

有这个:

BoxWithBallsCount(Box box, BoxCount boxCount)
BoxCount(String ballColor, int count)

我创建了以下道

@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);
}

现在我需要实现 main 方法:可流动的 returns BoxWithBallsCount 列表。 我该怎么做?

我尝试了很多 RX 方法,但找不到正确的方法。

谢谢

【问题讨论】:

  • 我认为更好的方法是在原始查询中使用子选择? SELECT * FROM t1 A, (SELECT count(*) AS count FROM t2 T2 where t1.id = t2.id) B WHERE A.id = B.id

标签: android rx-java rx-java2 android-room


【解决方案1】:

我创建了一个辅助函数来实现结果:

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);
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 2013-12-11
    • 2021-10-29
    • 2017-10-28
    • 2017-01-05
    相关资源
    最近更新 更多