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は最新の記録を保持します。
あなたは使用する必要があります
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ファイルを作成しません。ルームデータベースのエクスポートに支障をきたします。
DBファイルをエクスポートする場合:
私も同じ問題を抱えていました。 wal(ログ先行書き込み)をコピーする必要はありません。これは一時ファイルです。 documentation によると、データベースをインポートまたはエクスポートする前に、データベースへのすべての接続を閉じる必要があります。これで問題が解決し、メインデータベースファイルのみをコピーする必要があります。
データベースクラスの例:
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;
}
}