Android Room数据库联合Unique约束不生效,插入重复数据自动更新问题求助
问题根源
- 你为
lastTimeUsed和beginningTime设置了联合唯一约束,意味着这两个字段的组合在整张表中只能对应唯一一条记录,只要两者的组合值和已有数据重复,就会触发SQLite的冲突逻辑。 - Room插入操作如果没有显式指定冲突策略,或是你主动使用了
OnConflictStrategy.REPLACE策略,触发唯一约束冲突时就会删除原有冲突数据,再插入新的冲突数据,表现出来就是原有数据的isChild字段被更新。
调整方案
你可以根据自身业务需求选择以下任意一种方案:
方案1:扩展联合唯一约束的字段范围
如果你的业务允许同一lastTimeUsed+beginningTime组合对应多条isChild取值不同的记录,只需要把isChild也加入联合唯一约束的字段列表即可,修改后的实体类代码如下:
@Entity(tableName = "DailyGraphData", indices = [Index(value = arrayOf("lastTimeUsed","beginningTime", "isChild"), unique = true)]) data class DailyGraphData( @PrimaryKey(autoGenerate = true) val id: Int = 0, var appName: String, var packageName: String, var totalAppTimeInForeground: Long? = 0L, var lastTimeUsed: String? = "", var beginningTime: String? ="", var endTime: String? = "", var isChild: Boolean )
修改后需要卸载重装应用或做数据库迁移生效,后续插入时只有三个字段的组合完全重复才会触发冲突,你描述的场景中isChild取值不同,就会作为全新数据存入表中。
方案2:修改插入操作的冲突策略
如果你的业务要求lastTimeUsed+beginningTime组合必须全局唯一,冲突时需要保留原有数据不做修改,只需要调整DAO层插入方法的冲突策略即可,示例代码如下:
@Dao interface DailyGraphDataDao { @Insert(onConflict = OnConflictStrategy.IGNORE) fun insertDailyGraphDataList(dataList: List<DailyGraphData>) }
这个方案下,第二次插入的8条冲突数据会被直接忽略,只有2条全新数据会被插入,原有数据不会发生任何变更。
内容的提问来源于stack exchange,提问作者MARSH
相关产品推荐
相关产品推荐

