Android会议室数据库不会导出所有数据

时间:2018-03-20 21:50:21

标签: android android-sqlite android-room android-sql

我正在尝试设置Room数据库备份功能。 问题是sql数据库文件在下载后不包含应用程序中的最新数据集。它总是错过一些最近的记录。 有没有正确的方法来导出房间数据库? 附:使用sqliteHelper处理我的数据库时,我没有遇到类似的问题,所以我认为它必须与Room有关。

我正在这样做:

@Throws(IOException::class)
private fun copyAppDbToDownloadFolder(address: String) {
    val backupDB = File(address, "studioDb.db") 
    val currentDB = applicationContext.getDatabasePath(StudioDatabase.DB_NAME)
    if (currentDB.exists()) {
        val src = FileInputStream(currentDB).channel
        val dst = FileOutputStream(backupDB).channel
        dst.transferFrom(src, 0, src.size())
        src.close()
        dst.close()
    }
}

4 个答案:

答案 0 :(得分:4)

您需要使用

  

JournalMode.TRUNCATE

在您的AppDatabase.java中:

private static AppDatabase sInstance;

public static AppDatabase getDatabase(final Context context) {
    if (sInstance == null) {
        synchronized (AppDatabase.class) {
            if (sInstance == null) {
                sInstance = Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
                        .setJournalMode(JournalMode.TRUNCATE)
                        .build();
            }
        }
    }
    return sInstance;
}

此方法将不会创建在导出房间db时造成障碍的 db.bad db.wal 文件。

用于导出数据库文件:

  

链接:Exporting db with creating folder on daily basis

答案 1 :(得分:3)

我有同样的问题。你不需要复制wal(提前写日志文件)它是一个临时文件。根据{{​​3}},我们需要在导入或导出数据库之前关闭与数据库的所有连接。这解决了我的问题,现在我只需要复制主数据库文件。

数据库类示例:

public abstract class AppDB extends RoomDatabase {    

    private static final Object sLock = new Object();

    private static AppDB INSTANCE;

    // create new database connection
    public static AppDB getInstance(final Context context) {
        synchronized (sLock) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDB.class, "packagename")                    
                    .build();
                }
            return INSTANCE;
        }
    }

    // close database
    public static void destroyInstance(){
        if (INSTANCE.isOpen()) INSTANCE.close();
        INSTANCE = null;
    }
}

答案 2 :(得分:3)

kotlin:这对我有用

private fun exportDb() {
    val TABLE_NAME = "order_table"

    val exportDir = File(getExternalStorageDirectory(), "/CSV")// your path where you want save your file
    if (!exportDir.exists()) {
        exportDir.mkdirs()
    }

    val file = File(exportDir, "$TABLE_NAME.csv")


    try {
        file.createNewFile()
        val db: MenuItemsDatabase = MenuItemsDatabase.getDatabase(requireActivity())
        val csvWrite = CSVWriter(FileWriter(file))
        val curCSV: Cursor = db.query("SELECT * FROM order_table", null)
        csvWrite.writeNext(curCSV.getColumnNames())
        while (curCSV.moveToNext()) {
            //Which column you want to exprort
               val arrStr = arrayOfNulls<String>(curCSV.getColumnCount())
        
            for (i in 0 until curCSV.getColumnCount() - 1) arrStr[i] = curCSV.getString(i)
            csvWrite.writeNext(arrStr)
        }
        csvWrite.close()
        curCSV.close()
        Toast.makeText(context, "Exported", Toast.LENGTH_SHORT).show()

    } catch (sqlEx: java.lang.Exception) {
        //Log.e("Payment fragment", "Exported error", sqlEx)
        Toast.makeText(context, "Exported error", Toast.LENGTH_SHORT).show()
    }
}

答案 3 :(得分:2)

我已经解决了。导出(保存)使用Room处理的sql数据库时,必须导出(以后导入) - your_database.bd和your_database.wal文件。后来是期刊,afaiu保留最新记录。