如何使用 Android ROOM 数据库中的关系对子数据进行排序(一对多关系)

How to sort child data using relation in Android ROOM database which uses (One to many relationship)

商店实体

data class Store(
val storeId: Int,
val name: String,
val storeRank:Int
)

产品实体

data class Product(
val productId: Int,
val name: String
)

参考实体

data class Reff(
val storeId: Int,
val productId: Int,
val productRankInStore:Int
)

关系

data class StoreAndProduct(
@Embedded
val store: Store,
@Relation(
    entity = Product::class,
    parentColumn = "storeId",
    entityColumn = "productId",
    associateBy = Junction(
        parentColumn = "storeId",
        entityColumn = "productId",
        value = Reff::class
    )
)
val product: List<Product>


)

这里我需要使用关键字 productRankInStoreProducts 进行排序。我已经实现了关系并且工作正常。但是我找不到任何其他方法来使用 productRankInStore

对产品进行排序

注意:相同的产品在不同的商店有不同的排名(productRankInStore

如果你有一个抽象 class 而不是 @Dao 注释的接口 class(es) 那么你可以有效地覆盖 Room 处理 @Relation 的方式,使用一个执行两个阶段的函数, 后者相应排序。

您可以通过使用 2 个 @Query 来做到这一点:-

  • 主要(商店)和
  • 二次查询(商品按排名排序)

然后您将它们组合成一个函数,例如:-

@Dao
abstract class AllDAO {

    @Query("SELECT * FROM store")
    abstract fun getAllStores(): List<Store>
    @Query("SELECT product.* FROM reff JOIN product ON product.productId = reff.productId WHERE reff.storeId=:storeId ORDER BY productRankInStore DESC")
    abstract fun getStoreProductsSortedByRank(storeId: Int): List<Product>

    @Query("")
    @Transaction
    fun getStoreAndProductsSortedByProductRank(): List<StoreAndProduct> {
        val rv = arrayListOf<StoreAndProduct>()
        for (store in getAllStores() /* obviously change initial query if desired */) {
            rv.add(StoreAndProduct(store,getStoreProductsSortedByRank(store.storeId)))
        }
        return rv
    }
}

然后您可以使用:-

dao.getStoreAndProductsSortedByProductRank()

例如如果您的数据为:-

排名第一然后是以下

    for(s in dao.getStoreAndProductsSortedByProductRank()) {
        Log.d("DBINFO","Store is ${s.store.name}")
        for (p in s.product) {
            Log.d("DBINFO","\tProduct is ${p.name}")
        }
    }

将输出:-

2022-03-26 06:43:15.753 D/DBINFO: Store is Store1
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductA
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductB
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductC
2022-03-26 06:43:15.753 D/DBINFO: Store is Store2
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductC
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductA
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductB
2022-03-26 06:43:15.753 D/DBINFO: Store is Store3
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductC
2022-03-26 06:43:15.753 D/DBINFO:   Product is ProductB
2022-03-26 06:43:15.754 D/DBINFO:   Product is ProductA

注意 rankInStore 将不可用(根据您的 StoreAndProduct)。

  • 如果您需要可用的 rankInStore,那么您需要做一些事情,例如拥有并使用 ProductAndRank POJO。