【问题标题】:Room database Insert or update but keep a database field?房间数据库插入或更新但保留数据库字段?
【发布时间】:2018-01-04 17:30:12
【问题描述】:

我正在尝试实现以下场景 -> 从 API 获取记录并存储到数据库中。一些记录可能被点击为favorite,即使从 API 获取新数据,它们也应该保持不变。但是,我似乎无法找到如何在不替换整行的情况下不替换那些已经被选为favorite 的记录的方法。我试过一个一个地插入记录,并以某种方式在插入中检查记录是否已经存在,但我似乎无法使用 RxJava 弄清楚。

Dao

    @Dao
    interface KafanaDao {

    @Insert
    fun insertSingleKafana(kafana: Kafana)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(kafani: List<Kafana>)

    @Query("SELECT * FROM ${Constants.KAFANI_TABLE_NAME}")
    fun getKafani(): Single<List<Kafana>>

    @Query("SELECT * FROM ${Constants.KAFANI_TABLE_NAME} WHERE name = :name")
    fun getSingleKafana(name: String): Single<Kafana>

    @Query("UPDATE ${Constants.KAFANI_TABLE_NAME} SET isFavorite = :isFavorite WHERE name = :name")
    fun setFavourite(name: String, isFavorite: Int)
}

然后我不断地把记录一个一个地插入,但是如何检查它们是否已经存入数据库呢?

fun insertSingleKafanaInDb(kafana: Kafana) {
    Observable.fromCallable { kafanaDao.insertSingleKafana(kafana) }
            .subscribeOn(Schedulers.io())
            .subscribe {
                Timber.d("Inserted ${kafana.name} kafani from API in DB...")
            }
}

fun getKafaniFromApi(): Observable<List<Kafana>> {
    return apiService.getKafani().toObservable().doOnNext {
        for (kafana in it) {
            //I need to somehow do the check here
            insertSingleKafanaInDb(kafana)
        }
    }
}

Entity

    @Entity(tableName = Constants.KAFANI_TABLE_NAME)
    data class Kafana(
        @PrimaryKey
        @ColumnInfo(name = "name")
        @SerializedName("name")
        val name: String,
        @ColumnInfo(name = "phone")
        @SerializedName("phone")
        val phone: String,
        @ColumnInfo(name = "address")
        @SerializedName("address")
        val address: String,
        @ColumnInfo(name = "city")
        @SerializedName("city")
        val city: String,
        @ColumnInfo(name = "sponsored")
        @SerializedName("sponsored")
        val isSponsored: Boolean,
        @ColumnInfo(name = "isFavorite")
        var isFavorite: Boolean

)

【问题讨论】:

  • 由于您的冲突策略OnConflictStrategy.REPLACE,它被替换了。您需要使每一个都独一无二的东西,以便能够检查它是否存在
  • 什么是主键?是自动生成的还是 API 自带的
  • 我用Entity 编辑了我的问题。基本上我每次都打电话并替换数据库,因为可能会有新记录。不过,我不知道这是否是一个好习惯。
  • isFavourite 值来自API,我的意思是初始值?
  • 不,它不是来自API,初始值为false。

标签: android kotlin android-room


【解决方案1】:

可以通过两种方法完成

第一个:- 在插入 Kafane 之前,您查询 getSingleKafana(name: String): Single 并从数据库中获取它(如果可用)并获取收藏状态并将此收藏字段设置为 API 中新出现的 KAFANA 对象。

第二个: 做一个查询,它将返回 KAFANA 对象列表,其中收藏夹为真,结果将列表,在从 API 插入新的 KAFANA 之前检查 kafana 是否显示在列表中。

Room 不支持任何条件插入查询。它将插入整个对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多