在android中将房间数据库导出到csv文件

kin*_*tel 8 csv android export-to-csv kotlin android-room

有很多教程可用于将 SQLite 数据库导出到 csv 文件,但没有足够的东西从房间数据库导出。

使用 sqlite 导出参考将SQLite 数据库导出到 android 中的 csv 文件,手动解析每列行的空间。以下是我的代码:

     @Dao
     interface CategoryDao {
         @Query("SELECT * FROM Category")
         fun getAllCategory(): List<Category>
     }

//   Export csv logic

      val categoryList = categoryDao.getAllCategory()
      val csvWrite = CSVWriter(FileWriter(file))

      for (item in categoryList) {
         val arrStr = arrayOf<String>(item.categoryId, item.categoryName)
         csvWrite.writeNext(arrStr)
      }
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以导出csv。即使在房间里也没有实用地获取表的列名,因此无法为所有表创建动态通用逻辑。

Jem*_*rov 1

我尝试通过两种方法迭代大型 Room 数据库:

1-获取Cursor并迭代:

import android.database.Cursor
...
@Query("SELECT * FROM Category")
fun getAllCategory(): Cursor<Category>
...
val success = cursor.moveToFirst()
if (success) {
     while (!cursor.isAfterLast) {
         // Process items
         cursor.moveToNext()
     }
} else {
    // Empty
}
cursor.close()
Run Code Online (Sandbox Code Playgroud)

2- 用于PagedList一次获取 pageSize 数量的项目并进行处理。然后查询另一个页面并处理:

@Query("SELECT * FROM Category")
fun getAllCategory(): DataSource.Factory<Int, Category>

// Here i will return Flowable. You can return LiveData with 'LivePagedListBuilder'
fun getCategories(pageSize: Int): Flowable<PagedList<Category>> {
        val config = PagedList.Config.Builder()
                .setPageSize(pageSize)
                .setPrefetchDistance(pageSize / 4)
                .setEnablePlaceholders(true)
                .setInitialLoadSizeHint(pageSize)
                .build()
        return RxPagedListBuilder(categoryDao.getAllCategory(), config)
                .buildFlowable(BackpressureStrategy.BUFFER)
}
Run Code Online (Sandbox Code Playgroud)

现在上面的getCategories()函数将返回pagedList内部Flowableor LiveData。由于我们已经设置了setEnablePlaceholders(true)pagedList.size即使它不在内存中,也会显示整个大小。因此,如果pageSize为 50 并且所有数据大小为 1000,pagedList.size将返回 1000,但其中大部分将为空。查询下一页并处理:

// Callback is triggered when next page is loaded
pagedList.addWeakCallback(pagedList.snapshot(), object : PagedList.Callback() {
    override fun onChanged(position: Int, count: Int) {
        for (index in position until (position + count)) {
            if (index == (position + count - 1)) {
                if (index < (pagedList.size - 1)) 
                    pagedList.loadAround(index + 1)
                else{ 
                    // Last item is processed.
                }
            } else
                processCurrentValue(index, pagedList[index]!!)
        }
    }
    override fun onInserted(position: Int, count: Int) {
        // You better not change database while iterating over it 
    }    
    override fun onRemoved(position: Int, count: Int) {
        // You better not change database while iterating over it
    }
})

// Start to iterate and query next page when item is null.
for (index in 0 until pagedList.size) {
     if (pagedList[index] != null) {
            processCurrentValue(index, pagedList[index]!!)
     } else {
            // Query next page
            pagedList.loadAround(index)
            break
     }
}
Run Code Online (Sandbox Code Playgroud)

结论:在PagedList方法中,您可以一次获取数千行并进行处理,而在Cursor方法中,您可以逐行迭代。我发现PagedList当 pageSize > 3000 时不稳定。有时它不返回页面。所以我用了Cursor。在 Android 8 手机上,两种方法迭代(并处理)900k 行大约需要 5 分钟。

  • 问题是关于导出数据库,而不是关于如何使用 PAGING LIBRARY! (3认同)