새 테이블만 추가된 경우 회의실 데이터베이스 마이그레이션
간단한 회의실 데이터베이스가 있다고 가정합니다.
@Database(entities = {User.class}, version = 1)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
이제 새로운 엔티티를 추가하겠습니다.Pet
버전 2 버 2 핑 2 핑 2 and and and and and and and and and 。
@Database(entities = {User.class, Pet.class}, version = 2)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
입니다. "Room"은 "Room"입니다.java.lang.IllegalStateException: A migration from 1 to 2 is necessary.
가 변하지 가정하면User
합니다), tableclass(클래스)를해야 합니다.Room에서 생성된 클래스를 살펴보고 새 테이블을 만들기 위해 생성된 쿼리를 검색하여 복사하고 마이그레이션에 붙여넣습니다.
final Migration MIGRATION_1_2 =
new Migration(1, 2) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `Pet` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))");
}
};
하지만 수동으로 하는 것은 불편합니다.Room에게 알릴 방법이 있습니까?기존 테이블을 건드리지 않기 때문에 데이터는 안전합니다. 이행을 작성해 주시겠습니까?
회의실에 이행 시스템이 제대로 설치되어 있지 않습니다.적어도 다음 시간까지입니다.2.1.0-alpha03
.
따라서 이행 시스템이 개선될 때까지 회의실에서 이행이 용이한 몇 가지 회피책이 있습니다.
「 」와 같은 에,@Database(createNewTables = true)
★★★★★★★★★★★★★★★★★」MigrationSystem.createTable(User::class)
, 은 '실행하는
CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))
면 insidemigrate
★★★★★★ 。
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))")
}
}
SQL 스크립트를 능가하기 위해서는 4가지 방법이 있습니다.
1. 직접 쓰기
기본적으로 Room이 생성하는 스크립트와 일치하는 위의 스크립트를 작성해야 합니다.이 방법은 가능하지만 가능하지 않습니다. (50개의 필드가 있다고 가정합니다.)
2. 스키마의 내보내기
if if if if if if exportSchema = true
면 inside@Database
주석, 회의실은 프로젝트 폴더의 /schemas 내에 데이터베이스 스키마를 생성합니다.은 ★★★★★★★★★★★★★★★★.
@Database(entities = [User::class], version = 2, exportSchema = true)
abstract class AppDatabase : RoomDatabase {
//...
}
은 꼭 .build.grade
중 하나
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
때 파일 "JSON"이 됩니다.2.json
회의실 데이터베이스 내의 모든 쿼리를 포함합니다.
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "325bd539353db508c5248423a1c88c03",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
위의 을 넣을 수 .createSql
migrate
★★★★★★ 。
3. AppDatabase_Impl에서 쿼리를 가져옵니다.
않은 수 시 "Schema"는 "Schema는 "Schema"를 생성합니다.AppDatabase_Impl.java
을 사용법
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER, PRIMARY KEY(`id`))");
★★★내createAllTables
메서드에는 모든 엔티티의 작성 스크립트가 있습니다. 해서 안에 수 요.migrate
★★★★★★ 。
4. 주석 처리.
하신 바와 같이합니다.schema
, , , , 입니다.AppDatabase_Impl
내 및 with annotation Processing with 컴 files files files 。
kapt "androidx.room:room-compiler:$room_version"
즉, 동일한 작업을 수행하고 필요한 모든 작성 쿼리를 생성하는 주석 처리 라이브러리를 만들 수도 있습니다.
'방' 입니다.@Entity
★★★★★★★★★★★★★★★★★」@Database
주석이 달린 수업을 듣다@Entity
이렇게 할 단계는 다음과 같습니다.
- 로들기기를 작성하다
StringBuilder
'. - 을 「」에서 합니다.
class.simplename
★★★★★★★★★★★★★★★★★★」tableName
의@Entity
하다 보면요.StringBuilder
- 그런 다음 클래스의 각 필드에 대해 SQL 열을 만듭니다. 이름, 유형, 무효 중 하나로 가져옵니다.
@ColumnInfo
모든 더해야 합니다.id INTEGER NOT NULL
컬럼 스타일StringBuilder
. - 를 「」로 합니다.
@PrimaryKey
ForeignKey
★★★★★★★★★★★★★★★★★」Indices
존재하는 경우.- 종료 후 문자열로 변환하여 사용할 새 클래스에 저장합니다.예를 들어 다음과 같이 저장합니다.
public final class UserSqlUtils {
public String createTable = "CREATE TABLE IF NOT EXISTS User (id INTEGER, PRIMARY KEY(id))";
}
그 다음에, 다음과 같이 사용할 수 있습니다.
val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
제가 직접 만든 도서관은 대출도 되고 프로젝트에도 활용할 수 있습니다.제가 만든 라이브러리는 꽉 차 있지 않고 테이블 작성에 필요한 요건만 충족합니다.
도움이 됐으면 좋겠네요.
갱신하다
때은 이을 was was was was was was by by by by by by by by by by by by by by by by by by by 。2.1.0-alpha03
.
에서의 이행 시스템이 개선될 것으로 기대됩니다.
2.2.0
유감스럽게도 아직 더 나은 이행 시스템이 부족합니다.
죄송합니다. Room은 데이터 손실이 없는 테이블의 자동 생성을 지원하지 않습니다.
이행의 기입은 필수입니다.그렇지 않으면 모든 데이터가 지워지고 새 테이블 구조가 생성됩니다.
아직도 이 문제에 대한 해결책을 찾고 있는 사람들을 위해, 좋은 소식이 있습니다.Room이 버전 2.4.0을 사용한 자동 이행을 지원하기 시작했습니다.
https://developer.android.com/jetpack/androidx/releases/room#2.4.0-alpha01
다음 gradle 명령을 app.gradle의 defaultConfig에 추가할 수 있습니다.
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
이 작업을 실행하면 테이블 이름 목록이 관련 CREATE TABLE 문과 함께 컴파일되어 이행 객체에 복사하여 붙여넣기만 하면 됩니다.테이블 이름을 변경해야 할 수도 있습니다.
예를 들어, 이것은 생성된 스키마에서 가져온 것입니다.
"tableName": "assets",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`asset_id` INTEGER NOT NULL, `type` INTEGER NOT NULL, `base` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`asset_id`))"
따라서 createSql 문을 복사하여 붙여넣고 ${TAB}를 변경합니다.LE_NAME}'은 테이블 이름을 '자산'하고 voila는 자동으로 Room을 생성합니다.
이 경우(다른 테이블을 변경하지 않고 새 테이블만 작성한 경우) 마이그레이션이 전혀 생성되지 않고 이 작업을 수행할 수 있습니까?
이렇게 하면...
@Database(entities = {User.class, Pet.class}, version = 2)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
public abstract Dao getPetDao();
}
나머지 금액은 위에서 설명한 바와 같습니다.
db = Room.databaseBuilder(this, AppDatabase::class.java, "your_db")
.addMigrations(MIGRATION_1_2).build()
레퍼런스 - 상세 정보
이 경우 마이그레이션을 수행할 필요가 없습니다.데이터베이스 인스턴스를 작성할 때 .fallbackToDestructiveMigration()을 호출할 수 있습니다.
예:
instance = Room.databaseBuilder(context, AppDatabase.class, "database name").fallbackToDestructiveMigration().build();
데이터베이스 버전 변경도 잊지 마십시오.
언급URL : https://stackoverflow.com/questions/48399852/room-database-migration-if-only-new-table-is-added
'source' 카테고리의 다른 글
PHP에서 현재 페이지의 URL을 가져오는 방법 (0) | 2023.01.12 |
---|---|
pip install -U에서 "-U" 옵션은 무엇을 의미합니까? (0) | 2023.01.12 |
PHP에 의해 로드된 확장자는 어떻게 확인할 수 있습니까? (0) | 2023.01.12 |
python * 연산자의 고유 이름? (0) | 2023.01.12 |
Java의 큰 수 (0) | 2023.01.12 |