我有一个活动将解析json数据并在活动开始后使用greenDAO更新数据库。它的更新代码如下:
exampleDao.insertOrReplace(exampleObj);
但是当活动恢复并恢复时,它将继续插入导致重复数据输入与不同的主键但相同的数据,如何防止重复数据输入?
非常感谢
答案 0 :(得分:5)
由于您没有提供有关数据模型的架构或类似信息,因此这个答案只是猜测!
可能您使用的是自动增量主键。
这意味着您的主键可能未包含在您的JSON数据中,导致主键属性为null。
这告诉greendao这是一个新条目,greendao将插入一个带有新主键的新条目。
首先尝试读取对象,然后调用insertOrReplace:
Example oldObj;
try {
// Try to find the Example-Object if it is already existing.
oldObj = exampleDao.queryBuilder().where(someCondition).unique();
} catch (Exception ex) {
oldObj = null;
}
if (oldObj == null) {
oldObj = new Example();
}
// update oldObj with the data from JSON
exampleDao.insertOrReplace(oldObj);
答案 1 :(得分:2)
使列(my_Id中的其他列)唯一,并将其用作真正的主键。
答案 2 :(得分:1)
@Hiep的解决方案正确,但不完全正确:无需更改表的主键。
事实上,在所有实体的字段上添加@Unique
注释就足够了,应该对等式进行比较,GreenDao将处理其余部分:如果使用insertOrReplace
插入的实体是相等的一些已存储的实体的所有唯一字段,然后将删除旧实体并添加新实体。
请注意,此“交换”实际上是更新,但“已更新”实体的行ID(主键)将不同(因此该方法称为insertOrReplace
)。
所以,给定以下实体:
@Entity
public static class TestEntity {
@Id(autoincrement = true)
private Long id;
@Unique @NotNull private String code;
@NotNull private String description;
// constructor and getters/setters here
}
以下测试通过(您可以使用Robolectric运行):
@Test
public void insertOrReplace_nullRowIdSameUniqueField_existingEntryReplaced() {
// Arrange
TestEntity testEntity = new TestEntity(null, "code", "old description");
mDaoSession.getTestEntityDao().insert(testEntity);
assertThat(mDaoSession.getTestEntityDao().loadAll().size(), is(1)); // assert insertion succeeded
// Act
TestEntity testEntityOther = new TestEntity(null, "code", "new description");
mDaoSession.getTestEntityDao().insertOrReplace(testEntityOther);
// Assert
List<TestEntity> testEntityList = mDaoSession.getTestEntityDao().loadAll();
assertThat(testEntityList.size(), is(1)); // number of entities did not change
assertEquals(testEntityList.get(0).getCode(), "code"); // same code
assertEquals(testEntityList.get(0).getDescription(), "new description"); // updated description
}
答案 3 :(得分:0)
确保您的实体具有主键属性集(!= null)。