Android 房间数据库 insert/update 序列

Android room database insert/update sequence

我有一个带有 Room 数据库的应用程序,包括 DAO 和 Repository。事件顺序如下:

  1. 插入一个新行。
  2. 将行发送到服务器
  3. 更新该行以指示该行已发送。

问题是新行的 ID 在我发送到服务器之前或进行更新时并不总是可用。因此 DAO 更新方法不起作用,因为它没有正确的 ID。
在我继续之前,是否有使 Insert return 成为 ID 的技巧?我知道这是在规避异步进程的好处,但在这种情况下可能是必要的。 我希望其他人可能已经解决了这个问题。

The problem is that the ID of the new row is not always available before I send to the server

对于 Room 中的表,总是 一个唯一标识插入行的值,如果该行是通过便利的 @Insert 插入的(不同的问题,如果使用 @Query("INSERT INTO ....."))

  • 请注意,如果由于 trapped/handled 冲突而未插入该行,则 returned 的值将为 -1。

Is there a trick to making the Insert return the ID before I go on?

不是真正的技巧,至少如果 IDs 是整数类型,更多的是 expected/anticipated 用法。只需 insert Dao return Long(或 long if java)

例如(Java)

@Insert
long insert(TheEntity theEntity);

或(Kotlin)

@Insert
fun insert(theEntity: TheEntity): Long

Long/long returned 将是 rowid 列或其别名的值。

rowid 是所有表都有的列(除了那些用 WITHOUT ROWID 定义的表,Room 不允许),尽管它是一个隐藏列。如果您编写一个用 @PrimaryKey 注释的整数类型,那么该列将是 rowid.

的别名
  • 请注意您可能拥有的整数类型

    • 长,长,
    • 整数,整数,
    • 短,短,
    • 字节,字节,
    • 即使没用,布尔值,布尔值。
  • 但是,Long,long 是最适合 id 列的值,因为 SQLite 可以存储 64 位等于 Long/long 的有符号整数。因此为什么插入只能 return Long/long.

    • 不使用 Long/long 的优势微乎其微,SQLite 会将值存储在尽可能少的 space 中,从 1 个字节到 8 个字节。因此,值 1 byte/short/int/long 存储在数据库中时将占用一个字节。

    • 例如对于 Kotlin 代码 fun insert(toDoData: ToDoData): Int 你会得到 error: Not sure how to handle insert method's return type. public abstract int insert(@org.jetbrains.annotations.NotNull()

非整数 ID types/Composite 主键

其他列类型String、Byte[]、Double、Float等,或复合主键,将不会是rowid列的别名。要从这些其他类型中获取主键,您可以使用 rowid returned,因为它对行是唯一的,然后获取主键,例如(对于 @PrimaryKey val id: String

@Query("SELECT id FROM todo_table WHERE rowid=:rowid" )
fun getPrimaryKeyByRowid(rowid: Long): String`

当然你可以绕过获取 PrimayKey 值并传递然后使用 rowid 值来确定要更新的行,但不使用 @Update 方便 method/function 但 @Query 更新 UPDATE .... WHERE rowid=:passRowid.