Android 房间数据库不会导出所有数据
Android room database won't export all the data
我正在尝试设置 Room 数据库备份功能。
问题是 sql 数据库文件在下载后不包含应用程序中的最新数据集。它总是会遗漏一些最近的记录。
有导出房间数据库的正确方法吗?
P.S。使用 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()
}
}
我已经解决了。当导出(保存)您使用 Room 处理的 sql 数据库时,您必须同时导出(然后导入)- your_database.bd 和 your_database.wal 文件。后来是日记,afaiu 保留最新记录。
我有同样的问题。您不需要复制 wal(预写日志文件)它是一个临时文件。根据 documentation 我们需要在导入或导出数据库之前关闭与数据库的所有连接。这解决了我的问题,现在我只需要复制主数据库文件。
数据库示例class:
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;
}
}
您需要使用
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.bad 和 db.wal 文件,这些文件会阻碍导出房间数据库。
导出数据库文件:
Link: Exporting db with creating folder on daily basis
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()
}
}
我正在尝试设置 Room 数据库备份功能。 问题是 sql 数据库文件在下载后不包含应用程序中的最新数据集。它总是会遗漏一些最近的记录。 有导出房间数据库的正确方法吗? P.S。使用 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()
}
}
我已经解决了。当导出(保存)您使用 Room 处理的 sql 数据库时,您必须同时导出(然后导入)- your_database.bd 和 your_database.wal 文件。后来是日记,afaiu 保留最新记录。
我有同样的问题。您不需要复制 wal(预写日志文件)它是一个临时文件。根据 documentation 我们需要在导入或导出数据库之前关闭与数据库的所有连接。这解决了我的问题,现在我只需要复制主数据库文件。
数据库示例class:
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;
}
}
您需要使用
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.bad 和 db.wal 文件,这些文件会阻碍导出房间数据库。
导出数据库文件:
Link: Exporting db with creating folder on daily basis
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()
}
}