Room数据库插入或更新但保留数据库字段?

7
我正在尝试实现以下场景 -> 从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(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,它正在被替换。您需要使用使每个条目唯一的方法来检查其是否存在。 - tyczj
主键是什么?它是自动生成的还是在API中提供的? - lib4backer
我已经在我的问题中添加了“实体”(Entity)。基本上,我每次都进行调用并替换数据库,因为可能会有新的记录。但我不知道这是否是一个好的做法。 - Esteban
isFavourite的值来自API,我的意思是初始值是什么? - lib4backer
不,它不是来自API,初始值为false。 - Esteban
也许可以创建一个带有主键和isFavorite值的新表(实体)。 - LordRaydenMK
1个回答

5
可以通过两种方法来完成:
第一种方法:在插入Kafane之前,查询 getSingleKafana(name: String): Single 从数据库中获取它(如果可用),并获取其喜爱状态,将此喜爱字段设置为来自API的新KAFANA对象。
第二种方法:执行一个查询,其中返回带有favorite为true的KAFANA对象列表,结果将是List,在从API插入新的KAFANA之前,检查Kafana是否在列表中存在。
Room不支持任何条件插入查询。它将插入整个对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接