【问题标题】:How to insert a List of objects from an API to Room using Kotlin?如何使用 Kotlin 将 API 中的对象列表插入到 Room?
【发布时间】:2021-01-27 08:51:10
【问题描述】:

在我的应用程序中,我有一个简单的 Room 数据库,其中包含更新、插入、删除和 insertOrUpdate 等方法,它们检查是否存在具有主键的相同项目,并将其数量与新数量相加。

到目前为止的数据是由用户输入添加的,但现在用户将能够从远程服务器同步数据,所以我制作了一个 API,它返回与我的表结构相同的对象数组,我已尽一切努力在正确的对象类中获取列表,但现在哪种方法是在该对象列表上使用我的 insertOrUpdate 函数的最佳方式?我应该循环抛出每个项目并一项一项添加吗?

哪个是最好的解决方案?

这是我的 DAO 代码:

@Dao
interface ArticoliDAO {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(articolo: Articolo)

    @Update
    suspend fun update(articolo: Articolo)

    @Query("SELECT * FROM articoli_letti_table WHERE barcode = :key")
    suspend fun get(key: String): Articolo?

    @Query("UPDATE articoli_letti_table SET qta = qta + :qta WHERE barcode = :barcode")
    suspend fun updateQuantity(qta: Int, barcode: String)

    suspend fun insertOrUpdate(articolo: Articolo) {
        val itemFromDB = get(articolo.barcode)
        if (itemFromDB == null) {
            insert(articolo)
        }else {
            updateQuantity(articolo.qta, articolo.barcode)
        }

    }

    @Query("DELETE FROM articoli_letti_table WHERE barcode = :key")
    suspend fun delete(key: String)

    @Query("DELETE FROM articoli_letti_table")
    suspend fun clear()

    @Query("SELECT * FROM articoli_letti_table")
    fun getAll(): Flow<List<Articolo>>

}

这是我来自 SettingActivity 的代码,用户可以在其中按下“同步”按钮,将服务器中的所有项目添加到数据库中:

override fun onPreferenceTreeClick(preference: Preference?): Boolean {
    val key = preference?.key

    return when (key) {
        "sync" -> {
            val moshi = Moshi.Builder()
                .add(KotlinJsonAdapterFactory())
                .build()
            val retrofit = Retrofit.Builder()
                .baseUrl("http://192.168.100.65/VisualIntelligence/")
                .addConverterFactory(MoshiConverterFactory.create(moshi))
                .build()
            val service = retrofit.create(ArticoliService::class.java)
            val call = service.getArticoli()
            call.enqueue(object : Callback<List<Articolo>> {
                override fun onResponse(
                    call: Call<List<Articolo>>,
                    response: Response<List<Articolo>>
                ) {
                    if (response.code() == 200) {

                    }
                }

                override fun onFailure(call: Call<List<Articolo>>, t: Throwable) {
                    Log.e("ERR", t.message.toString())
                }

            })

            Snackbar.make(requireView(), "Sincronizzo gli articoli...", Snackbar.LENGTH_LONG).show()
            true
        }
        else -> true
    }
}

【问题讨论】:

  • 如果你可以insertList 为什么要一一插入呢?无论如何你的问题是什么?
  • 所以我应该在 DAO 中创建一个函数,在其中我传入 @Insert 整个列表?无论如何,问题是我应该使用 insertOrUpdate 就好像存在与其代码相同的项目我必须将它的旧数量与新的相加

标签: android api kotlin android-room


【解决方案1】:

您可以直接创建insertAll方法,以list为参数

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(articolo: List<Articolo>)

然后,只需在您的请求的onSuccess 中调用它

if (response.code() == 200) {
     articoloDao.insertAll(response.body())
}

【讨论】:

  • 嗨 rajan,如果发生冲突,它会替换项目,而我会使用我的 insertOrUpdate 来获取重复值并将其数量相加
  • 我猜在这种情况下,你只需要遍历每个项目,检查它是否已经存在,如果是更新或插入新记录
  • @IgorMytyuk 你能告诉我replaceupdate 之间的区别吗,如果你更新那么不匹配的字段值会改变,在替换整行的情况下会被替换.最后,结果将是相同的。您更新或替换的行的字段将具有相同的值。
【解决方案2】:

要么在此处循环列表并一一插入对象,要么创建一个适配器来处理数据库的插入列表,然后在此处循环并一一插入。

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2023-02-04
    • 1970-01-01
    相关资源
    最近更新 更多