通过DAO方法返回Map对象

问题描述 投票:0回答:2

我想在我的 dao 对象中有这样的方法

@Query("SELECT c.name, sum(p.value) FROM payments p, paymentCategories c WHERE p.categoryId = c.id GROUP BY c.name")
fun getCategoryStats(): Map<String, Float>

但我收到错误

错误:不确定如何将 Cursor 转换为该方法的返回类型 公共抽象 java.util.Map

是否可以将其更改为工作版本?

所以可以是不同类型的返回,但主要条件是

  1. 数据库中必须只有一个查询
  2. 我想避免额外的代码,例如仅为此方法创建额外的数据结构
android kotlin android-room
2个回答
13
投票

我参加聚会有点迟到了,但也许有人还会寻找它。

从 Room 2.4 开始,我们可以使用带注释的多重映射返回类型

@MapInfo
,这允许我们定义键和值的映射。

在你的情况下,它会是这样的:

@MapInfo(keyColumn = "name", valueColumn = "sum")    
@Query("SELECT c.name AS name, sum(p.value) AS sum FROM payments p, paymentCategories c WHERE p.categoryId = c.id GROUP BY c.name")
fun getCategoryStats(): Map<String, Float>

更多信息: https://developer.android.com/training/data-storage/room/accessing-data#multimap

更新

@MapInfo
已弃用。这是在 Kotlin 中执行此操作的新方法:

@Query("SELECT c.name AS name, sum(p.value) AS sum FROM payments p, paymentCategories c WHERE p.categoryId = c.id GROUP BY c.name")
suspend fun getCategoryStats(): Map<@MapColumn(columnName = "name") String, @MapColumn(columnName = "sum") Float>

0
投票

虽然我不认为这可以在 Dao 中完成,但在使用转换查询存储库或 viewModel(或查询列表的任何位置)中的 LiveData 时可以轻松完成。因为我不知道你的数据名,所以我使用的是虚构的:

val categoryStatsMap: LiveData<Map<String, Float>> = 
    Transformations.map(
        database.categoryStatsDao.getCategoryStats()) {it ->
            it.map {it.key to it.value}.toMap()
}

'it.key' 和 'it.value' 是实体对象中要用作映射中的键和值对的字段。 转换为您提供基于另一个实时数据对象的实时数据对象。我不知道开销是多少,但我认为应该不会太大。

© www.soinside.com 2019 - 2024. All rights reserved.