Room 데이터베이스를 제공하도록 앱을 업그레이드했습니다. 사용자가 새 앱 버전으로 업그레이드 할 때 다른 데이터 구조에 저장된 데이터를 Room Database로 가져와야합니다. 언뜻 보면 Room이 이미이 시나리오를 지원하는 것 같습니다.
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
// IMPORT DATA
}
})
.build();
그러나 실제로 데이터를 가져 오려고하면 상황이 더 복잡해집니다. Entities, Daos 및 AppDatabase를 사용하여 데이터를 가져 오려고하면 예외가 발생합니다.
java.lang.IllegalStateException : getDatabase가 재귀 적으로 호출 됨
모든 멋진 Room Entities, Daos 등을 사용하여 데이터베이스로 데이터를 가져올 수없는 것 같습니다. onCreate
방법은 그러나 기본 SQLite 데이터베이스에 대한 액세스를 제공 않습니다. 거기에 데이터를 가져와야할까요?
SQLite 데이터베이스를 직접 사용하는 것에 대한 문서 는 다소 얇습니다. 그리고 SQLite 데이터베이스에 직접 액세스하지 말고 대신 Room 추상화를 사용하라는 큰 빨간색 경고로 시작합니다!
어떻게 진행해야합니까? 일반적으로 어떻게 수행됩니까?
엔티티로 정의한 테이블이 이미 존재합니까? 아니면 데이터 가져 오기를 시작하기 전에 SQL 문으로 테이블을 만들어야합니까?
기본적으로 생성시 데이터를 Room 데이터베이스로 가져 오는 두 가지 방법이 있습니다. 첫 번째는 추악한 해결 방법을 사용하지만 Room Entities 및 모든 것을 사용할 수 있습니다. 두 번째는 제공된 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();
내가 생각했던 것보다 훨씬 덜 고통 스럽습니다. 오류가 발생하기 쉬운 데이터베이스 테이블과 필드를 식별하려면 문자열로 작업해야합니다!
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다