房间 - 插入或替换,但保留数据库字段?

Bol*_*aul 8 sqlite android android-sqlite android-room

我在我的本地数据库中有一个名为event的表,其中包含以下字段:

  • id(PK)
  • 姓名(文字)
  • 约会时间)
  • 最喜欢的(int,0或1)

服务器会给我一个事件列表,没有收藏字段,最喜欢的字段只是本地的.

我正在使用此代码插入事件

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertEvents(List<Event> events);
Run Code Online (Sandbox Code Playgroud)

问题是,如果一个事件已经存储在本地数据库中,它将丢失最喜欢的属性,并且在插入和替换之后它将始终为false.

有没有办法像这样批量插入,但保留最喜欢的字段?

小智 5

我也遇到过同样的情况。我就是这样解决的。由于来自服务器的数据是不可变的并且会重置本地值,因此我决定为来自服务器的数据保留一个表,并为“本地”数据保留另一个表。

ServerData远程数据表。

ServerDataAttrs仅用于本地数据的表。

ServerDataAttrs包含所有本地列以及idtable 中的主键ServerData

ServerData.id == ServerDataAttrs.id
Run Code Online (Sandbox Code Playgroud)

这样,来自的每一行都ServerDataAttrs与其对应的行相关ServerData(不需要相反的方式,这就是我稍后使用的原因LEFT JOIN)。您可以随时替换上的数据,ServerData并且本地数据ServerDataAttrs将保持不变。

我没有设置外键以避免意外删除。我仅在从其DAO.

为了查询数据,您可以创建一个POJO包含所有远程和本地值的集合。

public class ServerDataWithAttrsPojo {
   private long id;
   private String name;
   ...
   private int favorite;

   // public constructor, getters and setters...
}
Run Code Online (Sandbox Code Playgroud)

查询必须JOIN在两个表之间。

SELECT sd.id, sd.name, ...., sda.favorite
FROM ServerData sd LEFT JOIN ServerDataAttrs sda ON sd.id = sda.id
Run Code Online (Sandbox Code Playgroud)

我使用LEFT JOIN以防万一来自的实体ServerData没有ServerDataAttrs我之前提到的行。


jli*_*ely 2

我遇到了同样的问题,这就是我解决该问题的方案。

  • 检查您的数据库中是否有最喜欢的项目并获取它们。
  • 从API获取数据。
  • 将所有数据插入DB。
  • 使用之前获取的已标记为收藏的项目更新您的数据库。