一次将对象列表插入我的房间数据库,并更改对象的顺序

Insert a list of objects into my room database at once, and the order of objects is changed

我试图从我的遗留 litepal 数据库中插入一个对象列表到我的房间数据库中,当我从我的房间数据库中检索它们时,我发现我的对象的顺序不再与我的旧对象的顺序相同列表。 下面是我的代码:

// litepal is my legacy database
val litepalNoteList = LitePal.findAll(Note::class.java)

    if (litepalNoteList.isNotEmpty()) {

    litepalNoteList.forEach { note ->

        // before insertion, I want to trun my legacy note objects into Traininglog objects
        // note and Traninglog are of different types, but their content should be the same
        val noteContent = note.note_content
        val htmlContent = note.html_note_content
        val createdDate = note.created_date
        val isMarked = note.isLevelUp

        val legacyLog = TrainingLog(
            noteContent = noteContent,
            htmlLogContent = htmlContent,
            createdDate = createdDate,
            isMarked = isMarked)

        logViewModel.viewModelScope.launch(Dispatchers.IO) {
            trainingLogDao.insertNewTrainingLog(legacyLog)
    } // the end of forEach
}

问题是在我的房间数据库中,TraningLog 对象的顺序与我在 Litepal 数据库中的旧列表的顺序随机不同。

有人知道为什么会这样吗?

如果顺序很重要,那么您应该使用 ORDER BY 短语提取数据。否则,您会将订单留给查询优化器。

所以说而不是 @Query("SELECT * FROM trainingLog") 那么你可以使用 @Query("SELECT * FROM trainingLog ORDER BY createdDate ASC")

来排序结果

通过在 createdDate column/field(在 @ColumnInfo(index = true) 房间)上建立索引,可以提高提取上述内容的效率。但是,应该注意的是,拥有索引会产生开销。插入、删除和更新可能会产生额外的处理以维护索引。此外,索引使用更多 space.

您可能希望有一个可以获取列表而不是 运行 多线程插入的插入函数。然后 Room 将(我相信)在单个事务中执行所有插入操作(1 个磁盘写入而不是多个)。

例如

代替或以及

@Insert
fun insert(trainingLog: TrainingLog): Long

你可以

@Insert
fun insert(trainingLogList: List<TrainingLog>): LongArray

然后您需要做的就是在循环中构建列表,然后在循环之后调用单个插入。