首页 > 解决方案 > 如何使用 Kotlin 将 API 中的对象列表插入到 Room?

问题描述

在我的应用程序中,我有一个简单的 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
    }
}

标签: androidapikotlinandroid-room

解决方案


您可以直接使用as 参数创建insertAll方法list

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

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

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

推荐阅读