Android 房间数据库 insert/update 序列
Android room database insert/update sequence
我有一个带有 Room 数据库的应用程序,包括 DAO 和 Repository。事件顺序如下:
- 插入一个新行。
- 将行发送到服务器
- 更新该行以指示该行已发送。
问题是新行的 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
.
我有一个带有 Room 数据库的应用程序,包括 DAO 和 Repository。事件顺序如下:
- 插入一个新行。
- 将行发送到服务器
- 更新该行以指示该行已发送。
问题是新行的 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
.