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

dnph8jn4  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(225)

我有以下实体:

@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会自动填充我的值,但由于“local”不是来自服务器,因此它不会填充到该对象中。
当我调用update时,有没有一种方法可以让Room跳过“local”列的更新,而不编写自定义更新来插入到除“local”之外的所有其他列中?难点在于,我可能有许多列,并且我添加的每个新列都必须添加到自定义插入语句中。
我还想到了从服务器实体到新的“本地”实体的一对一Map,但是现在我必须在获得实体的任何地方处理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,并且它不会使用该更新语句进行编译。
有什么想法吗?

zynd9foi

zynd9foi1#

已将部分更新添加到2.2.0中的工作室
在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

o75abkj4

o75abkj42#

简单的回答是。房间没有条件插入或部分插入。
你必须想出你的插入逻辑。我想最好的一个是同时调用数据库和服务器来获取数据,然后用你的数据库响应的local值来更新你的服务器响应的local值。
如果您对 Rx 感到满意,则可以执行以下操作

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

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

相关问题