1 User 类
只有 3 个字段:id, username, password
其中 id 是主键, 并且是自增长
2 dao 类
使用 @Insert 注解如下:
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long saveUser(User user);
3 调用
不管是新增还是修改, 其他地方都是调用该方法:
dao.saveUser(user);
4 问题
然后, 发现一个有趣的现象, 有时候引用 user 时会失效, 查看数据库时发现, 指定 id 的数据已经不存在。
5 为什么会这样?
来自 stackoverflow 的解释:
@Insert(onConflict = OnConflictStrategy.REPLACE) 注解, 如果指定 id 的对象没有保存在数据库中, 就会新增一条数据到数据库。如果指定 id 的对象数据已经保存到数据库中, 就会删除掉原来的数据, 然后新增一条数据。
这样就解释了为什么引用 user 会失效。
原话如下:
A method, annotated with @Insert can return a long. This is the newly generated ID for the inserted row. A method, annotated with @Update can return an int. This is the number of updated rows.
update will try to update all your fields using the value of the primary key in a where clause. If your entity is not persisted in the database yet, the update query will not be able to find a row and will not update anything.
You can use @Insert(onConflict = OnConflictStrategy.REPLACE). This will try to insert the entity and, if there is an existing row that has the same ID value, it will delete it and replace it with the entity you are trying to insert. Be aware that, if you are using auto generated IDs, this means that the the resulting row will have a different ID than the original that was replaced. If you want to preserve the ID, then you have to come up with a custom way to do it.
来源:
https://stackoverflow.com/questions/48519896/room-update-or-insert-if-not-exist-rows-and-return-count-changed-rows
6 疑惑:
但是, 事情总是有但是, 经过测试发现, 修改了 username 或者 password, id 并没有改变。
这是怎么回事? id 的改变有条件呢? 还是版本不同才引起测试结果不同?
哪位 v 友能否解释下?
技术: android Room
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.