Room中是否可以忽略基本更新中的字段

时间:2019-04-23 06:36:55

标签: android gson android-room

我有以下实体:

@Entity
class Foo(
    @PrimaryKey
    @ColumnInfo(name = "id")
    val id: Long,

    @ColumnInfo(name = "thing1")
    val thing1: String,

    @ColumnInfo(name = "thing2")
    val thing2: String,

    @ColumnInfo(name = "thing3")
    val thing3: String,

    @ColumnInfo(name = "thing4")
    val thing4: String
) {

    @ColumnInfo(name = "local")
    var local: String? = null

}

本地是未存储在服务器上的信息,仅在电话本地。

当前,当我从服务器提取信息时,GSON会自动填写我的值,但是由于“本地”不是来自服务器,因此不会在该对象中填充。

有没有一种方法,当我调用更新时,可以让Room跳过“本地”列的更新,而无需编写自定义更新以插入到“本地”以外的所有其他列中?痛苦的是,我可能有很多列,并且我要添加的每个新列都必须将其添加到自定义插入语句中。

我还想到了从服务器实体到新的“本地”实体的一对一映射,但是现在我必须在得到实体的任何地方都处理join语句的痛苦,因为我需要本地信息。

我希望我可以做这样的事情:

@Entity
class Foo(
    @PrimaryKey
    @ColumnInfo(name = "id")
    val id: Long,

    @ColumnInfo(name = "thing1")
    val instructions: String,

    @ColumnInfo(name = "thing2")
    val instructions: String,

    @ColumnInfo(name = "thing3")
    val instructions: String,

    @ColumnInfo(name = "thing4")
    val instructions: String
) {

    @Ignore
    var local: String? = null

}

使用@Ignore批注,尝试忽略常规更新上的本地字符串。然后提供自定义更新语句,仅保存本地信息

@Query("UPDATE foo SET local = :newLocal WHERE foo.id = :id")
fun updateLocal(id: Long, newLocal: String)

但是ROOM似乎足够聪明,可以检查我是否在本地属性上使用@Ignore,并且它不会与该更新语句一起编译。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

部分更新已添加到2.2.0的Room中

在Dao中,您可以执行以下操作:

// Here you specify the target entity
@Update(entity = Foo::class)
fun update(partialFoo: PartialFoo)

并沿着您的实体Foo创建一个PartialFoo,其中包含主键和要更新的字段。

@Entity 
class PartialFoo {
    @ColumnInfo(name = "id")
    val id: Long,

    @ColumnInfo(name = "thing1")
    val instructions: String,
}

https://stackoverflow.com/a/59834309/1724097

答案 1 :(得分:0)

简单的答案是。房间没有条件插入或部分插入。

您必须提出插入逻辑。我猜最好的方法是同时调用数据库和服务器来获取数据,并仅用数据库响应的local值更新服务器响应的local值。

如果您对 Rx 感到满意,则可以执行以下操作

localDb.getFoo("id")
    .zipWith(
        remoteServer.getFoo("id"),
        BiFunction<Foo, Foo, Foo> { localFoo, remoteFoo -> 
            remoteFoo.local = localFoo.local
            remoteFoo
        }
    )

另一种可能的方法是编写自定义@Query,插入除本地以外的所有值,但是如果您有很多字段,这是不可行的。