之前,我预先填充了一些数据并将其添加到Room数据库中。但是我需要添加一些新数据。作为添加这些数据的一种方法,我可以通过直接请求dao来完成,但是应用程序每次打开时都会这样做。这将给应用程序带来不必要的负担。因此,是否有比下面的代码更好的方法?我想知道是否有比这更好的方法。
private fun addNewWord(){
val newWord1 = Word(1, "John", "Weight")
val newWord2 = Word(2, "Alex", "So"
wordViewModel.addWord(newWord1, newWord2)
}
我找到了一个类似上面代码的解决方案,但我认为它不够正确。我正在寻找一个更好的方法。这是一个最佳实践吗?
1条答案
按热度按时间3pmvbmvn1#
有许多更好的(只要 * 这将给应用程序带来不必要的负担 *),假设不必要的负担是与每当应用程序运行时尝试插入记录相关的开销(每当数据库打开时更正确)。
最简单的解决方案,但不是真正更好的解决方案(甚至可能是您尝试过的)是忽略重复项(如果您还没有忽略它们的话),这涉及到使用
INSERT OR IGNORE ....
,其中一个或多个列或列的组合具有UNQIUE索引。所有房间表(FTS(全文搜索)除外)都必须具有主键。主键隐式为UNIQUE。因此,如果使用
INSERT OR IGNORE ....
,则将忽略UNIQUE CONFLICT(不插入行,并忽略会导致异常的冲突)。要指定INSERT OR IGNORE以方便@Insert,则可以指定@Insert注解的onConflict值。例如
@Insert
返回插入行的rowid,或者如果由于忽略该行而没有插入该行,则返回-1,这可以被检查以查看是否插入了行。您还可以通过
@Entity
注解的indicies
参数为列或列组合指定唯一索引,例如:-但是,这个简单的解决方案仍然会运行,并在应用程序运行时尝试插入新数据。
没有 “不必要负担”的更好解决方案
如果目标是只应用一次新数据,则需要有一种方法来查看数据是否已经应用,可能是通过迁移(即新版本)。
迁移将仅运行一次,因为用户版本是数据库文件头的一部分,由Room检查/更新。
如果在指定新数据库版本后安装应用程序,也将运行迁移。
工作演示
也许可以考虑以下基于迁移的工作演示,基于您的数据似乎是:-
房间数据库代码:-
使用的活动代码为:-
例如,它只是访问数据库,提取所有行并将数据写入日志。
当在数据库版本1上作为新安装运行时,日志的输出为:-
如果再次运行,仍然是版本1,则输出为:-
也就是说,预打包数据库的副本没有被调用,因为数据库已经存在,否则输出是相同的。
如果数据库版本更改为2(无模式更改)且重新运行应用程序,则输出为:-
即调用迁移,并按照迁移中的代码引入新数据。
如果重新运行应用程序(仍为版本2),则:-
即不调用迁移,所有数据保留。
如果应用程序被卸载,然后安装/运行(根据新安装),则:-
即,已复制预打包数据库并调用迁移,从而引入新数据(不在预打包数据库中)。