Android 房间和视图模型,多个查询?

Android 房间和视图模型,多个查询?,android,android-room,android-livedata,android-viewmodel,Android,Android Room,Android Livedata,Android Viewmodel,因此,我有一个android应用程序,它有一个房间数据库,这个后端由一个类管理,这个类充当一个存储库,为我的视图模型提供信息,然后我的活动(片段)观察视图模型(每个人都和我在一起吗?),在我的片段中,我想得到所有卡片(实体)的列表在我的数据库中,单击值大于X,但我还希望获得标记为收藏的所有卡,而不管它们的单击值如何 我当前的解决方案是通过我的存储库从我的视图模型中运行两个独立的查询,我让我的活动观察这两个查询,并将返回的列表组合在一起,这不能正常工作,因为我的列表增加了一倍,我没有一个很好的地方

因此,我有一个android应用程序,它有一个房间数据库,这个后端由一个类管理,这个类充当一个存储库,为我的视图模型提供信息,然后我的活动(片段)观察视图模型(每个人都和我在一起吗?),在我的片段中,我想得到所有卡片(实体)的列表在我的数据库中,单击值大于X,但我还希望获得标记为收藏的所有卡,而不管它们的单击值如何

我当前的解决方案是通过我的存储库从我的视图模型中运行两个独立的查询,我让我的活动观察这两个查询,并将返回的列表组合在一起,这不能正常工作,因为我的列表增加了一倍,我没有一个很好的地方来清除列表,因为观察者在不同的时间回来,因为它们是异步的(我将发布所有代码)

我想我想要的是以某种方式合并查询,这样我只管理一个列表,但我的SQL知识不是很好,我不确定这是否可行,或者我可以以某种方式在我的存储库类中合并这些列表,但因为我使用的是实时数据,我不确定如何安全地获取数据以合并列表,但也许有一个我不知道的更好的解决方案,但我会在下面公布我目前正在做的事情

DAO查询 这是我运行的两个查询,一个获取所有卡片的点击次数x,另一个获取标记为收藏的所有卡片,这两个查询都使用了一个搜索字符串,但现在不相关

@Query("SELECT * FROM card WHERE cardFavourite AND cardWord LIKE :searchWord ORDER BY cardWord ASC")
LiveData<List<Card>> searchFavourites(String searchWord);

@Query("SELECT * FROM card WHERE cardClicked >= :clicks AND cardKeyStage <= :keystage  AND cardWord LIKE :searchWord ORDER BY cardFavourite ASC, cardClicked DESC, cardWord ASC")
LiveData<List<Card>> searchCardListRecents(String searchWord,int clicks, int keystage);
@Query(“从CardFavorite和cardWord类似的卡片中选择*:按cardWord ASC搜索单词顺序”)
LiveData搜索收藏夹(字符串搜索词);

@查询(“从cardClicked>=”所在的卡中选择*:单击和cardKeyStage如果第二个查询已经正常工作,则您还可以使用CardFavorite列

    @Query("SELECT * FROM card WHERE cardFavourite AND cardWord LIKE :searchWord ORDER BY cardWord ASC")
        LiveData<List<Card>> searchFavourites(String searchWord);


   @Query("SELECT * FROM card WHERE cardFavourite AND cardClicked >= :clicks AND cardKeyStage <= :keystage  AND cardWord LIKE :searchWord ORDER BY cardFavourite ASC, cardClicked DESC, cardWord ASC")
        LiveData<List<Card>> searchCardListRecents(String searchWord,int clicks, int keystage);
@Query(“从CardFavorite和cardWord类似的卡片中选择*:按cardWord ASC搜索单词顺序”)
LiveData搜索收藏夹(字符串搜索词);

@查询(“从CardFavorite和cardClicked>=:clicks和cardKeyStage中选择*)您可以尝试以下操作:

 @Query("SELECT * FROM card WHERE cardFavourite OR (cardClicked >= :clicks AND cardKeyStage <= :keystage)  AND cardWord LIKE :searchWord ORDER BY cardFavourite ASC, cardClicked DESC, cardWord ASC")
    LiveData<List<Card>> searchCardListRecentsAndFavourites(String searchWord,int clicks, int keystage);
    // Kotlin!!
    val allCardsLiveData = multiSourceLiveData(
        source1 = cardFavouritesViewModel.getLiveCardFavouriteList(),
        source2 = cardFavouritesViewModel.getLiveCardFavouriteList()
    ) { data1, data2 ->
        (data1 ?: emptyList()).plus(data2 ?: emptyList())
    }
    allCardsLiveData.observer(this) { allCards ->
        cardAdapter.refreshList(allCards);
        checkResults(cardArrayList.size());
    }

@Query(“从CardFavorite或(cardClicked>=:clicks AND cardKeyStage)所在的卡中选择*”此功能可能会有所帮助:

// Kotlin!!
fun <S, T, R> multiSourceLiveData(source1: LiveData<S>, source2: LiveData<T>, block: (S?, T?) -> R): LiveData<R> = MediatorLiveData<R>().apply {
    var data1: S? = null
    var data2: T? = null

    addSource(source1) {
        data1 = it
        value = block(data1, data2)
    }
    addSource(source2) {
        data2 = it
        value = block(data1, data2)
    }
}

//Java!!
LiveData allCardsLiveData=ExtensionsKt.multiSourceLiveData(
CardFavoriteSViewModel.GetLiveCardFavoriteList(),
CardFavoritesViewModel.getLiveCardRecentsList(),
新功能2(){
@凌驾
公共列表调用(列表数据1、列表数据2){
列表结果=新建ArrayList();
if(data1!=null)result.addAll(data1)
if(data2!=null)result.addAll(data2)
返回结果;
}
});
所有卡片滑动数据。观察(。。。

您可以对函数进行多个重载以支持不同数量的源。

这不会返回标记为收藏夹的卡,因为单击值为0,我在最初的问题中没有明确说明这一点,因此我对其进行了编辑以使其更清楚,我要所有标记为收藏夹的卡,以及所有值高于0的卡如果它们不是最受欢迎的,但我想要两者,我想要所有被标记为最受欢迎的卡片,以及点击值大于X的卡片,我还没有试过你的答案,所以当我有机会时,我会更新它,你得到了这两个:我在查询中使用OR运算符,即如果记录被标记为最受欢迎,你得到了它,如果点击>X,你也得到了结果
 @Query("SELECT * FROM card WHERE cardFavourite OR (cardClicked >= :clicks AND cardKeyStage <= :keystage)  AND cardWord LIKE :searchWord ORDER BY cardFavourite ASC, cardClicked DESC, cardWord ASC")
    LiveData<List<Card>> searchCardListRecentsAndFavourites(String searchWord,int clicks, int keystage);
// Kotlin!!
fun <S, T, R> multiSourceLiveData(source1: LiveData<S>, source2: LiveData<T>, block: (S?, T?) -> R): LiveData<R> = MediatorLiveData<R>().apply {
    var data1: S? = null
    var data2: T? = null

    addSource(source1) {
        data1 = it
        value = block(data1, data2)
    }
    addSource(source2) {
        data2 = it
        value = block(data1, data2)
    }
}
    // Kotlin!!
    val allCardsLiveData = multiSourceLiveData(
        source1 = cardFavouritesViewModel.getLiveCardFavouriteList(),
        source2 = cardFavouritesViewModel.getLiveCardFavouriteList()
    ) { data1, data2 ->
        (data1 ?: emptyList()).plus(data2 ?: emptyList())
    }
    allCardsLiveData.observer(this) { allCards ->
        cardAdapter.refreshList(allCards);
        checkResults(cardArrayList.size());
    }
    // Java!!
    LiveData<List<Card>> allCardsLiveData = ExtensionsKt.multiSourceLiveData(
            cardFavouritesViewModel.getLiveCardFavouriteList(),
            cardFavouritesViewModel.getLiveCardRecentsList(),
            new Function2<List<Card>, List<Card>, List<Card>>() {
                @Override
                public List<Card> invoke(List<Card> data1, List<Card> data2) {
                    List<Card> result = new ArrayList<>();
                    if (data1 != null) result.addAll(data1)
                    if (data2 != null) result.addAll(data2)
                    return result;
                }
            });

     allCardsLiveData.observe(...