Есть два основных способа импортировать данные в базу данных Room после создания. Первый использует уродливый обходной путь, но затем позволяет использовать объекты комнаты и все такое. Второй - работать напрямую с предоставленным экземпляром SQLiteDatabase.
1. Вставьте охранник и работайте с абстракциями комнаты
final boolean[] doImport = { false };
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
doImport[0] = true;
}
})
.build();
db.userDao().get(17);
if (doImport[0]) {
UserEntity user = new UserEntity();
user.name = "John Doe";
db.userDao().insert(user);
}
Логическое значение doImport
служит защитой протокола, независимо от того, был ли вызван обратный вызов onCreate
. Однако это должен быть массив, потому что новое значение не может быть присвоено простому логическому значению изнутри onCreate
.
Обратите внимание на кажущуюся бессмысленной строку db.userDao().get(17);
. Для вызова обратного вызова onCreate
необходим доступ к базе данных. В противном случае doImport
останется false
на этом этапе, независимо от того, была ли база данных создана заново.
Наконец, в последнем блоке if
к базе данных можно получить доступ со всеми красивыми абстракциями, которые предоставляет Room .
2. Работать напрямую с SQLiteDatabase
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
db.beginTransaction();
ContentValues values = new ContentValues();
values.put("name", "John Doe");
db.insert("UserEntity", SQLiteDatabase.CONFLICT_ABORT, values);
db.setTransactionSuccessful();
db.endTransaction();
}
})
.build();
Намного менее болезненно, чем я подозревал. Однако вам нужно работать со строками, чтобы идентифицировать таблицы и поля базы данных, что подвержено ошибкам!