ANDROID/Android 개발 이슈 & 해결

[Android] Room Migration : 데이터베이스 테이블 수정하기

주 녕 2022. 3. 26. 00:44
728x90

개발을 하다보니 Room의 엔티티를 바꾸거나 컬럼 속성을 바꿔야 하는 경우가 발생했다.

Sqllite을 기반으로 했기 때문에 쿼리문도 Sqllite로 작성하면 된다.

여기에서 발생한 이슈 사항을 정리하는 포스팅이다!

 

Room Migration

데이터베이스에 테이블이 추가, 삭제되는 등 변경이 발생했을 때 버전만 올린다면 기존의 데이터에 영향을 끼칠 수 있다.

Migration을 하기 위해서는 다음과 같은 순서를 따르면 된다.

  1. 데이터베이스의 버전 수정하기 (테이블을 추가하거나 삭제한다면 entities도 수정하기)
  2. Migration 정보를 담을 Migration 객체 생성하기
  3. 데이터베이스에 Migration 객체 추가하기

 

1. 데이터베이스 버전 수정하기

@Database(entities = [...], version = 1)
abstract class Database: RoomDatabase() {
	...
}
  • entities : Migration이 진행된 이후 사용될 엔티티들을 선언한다. (ex. 테이블 추가 → 해당되는 데이터 클래스를 추가)
  • version : Migration이 진행된 이후의 버전을 선언한다. (ex. 처음 Migration을 진행 → version = 2)

 

2. Migration 객체 생성하기

데이터베이스 클래스 안에 Migration 객체를 생성한다.

Migration(현재 버전, 다음 버전)으로 생성하고, migrate() 메서드를 오버라이딩 하여 실행할 쿼리문을 작성하면 된다.

    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(진행할 쿼리문)
            }
        }

 

진행할 쿼리문은 원하는 Sqllite 쿼리문을 작성하여 실행하면 된다.

아래에서는 테이블 추가, 삭제, 테이블명 변경, 컬럼 추가를 다뤘다.

테이블 추가

"CREATE TABLE 테이블명 ('categoryNo' INTEGER NOT NULL, 'name' TEXT NOT NULL, PRIMARY KEY('categoryNo'))"
  • CREATE TABLE 테이블명 ()
  • 각 컬럼의 이름, 타입, NULL 허용 여부, 디폴트값, PRIMARY KEY, FOREIGN KEY 등을 선언하면 된다.
  • 이 선언은 @Entity로 선언한 데이터 클래스와 동일하게 작성해야 한다.

☝️ Sqllite는 Boolean 타입을 Integer타입으로 저장한다

→ @Entity로 선언한 데이터 클래스에서는 Boolean이어도 쿼리문에서는 INTEGER로 작성해야 한다. ('0' = false / '1' = true)

→ @Entity로 선언한 데이터 클래스에서 defaultValue를 설정할 경우, '1' or '0'으로 설정해야 한다.

테이블 삭제

"DROP TABLE 테이블명"

테이블명 변경

"ALTER TABLE 이전테이블명 RENAME TO 현재테이블명"

테이블에 컬럼 추가

"ALTER TABLE 테이블명 ADD COLUMN 컬럼명 타입 ... "

 

3. 데이터베이스에 Migration 객체 추가하기

    companion object {
        private var INSTANCE: Database? = null
        fun getDatabase(context: Context): Database {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    Database::class.java, "데이터베이스명" )
                    .addMigrations(MIGRATION_1_2)  // 추가하기
                    .build()
                INSTANCE = instance
                instance
            }
        }

        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE Done ADD COLUMN 'tagNo' INTEGER")
                database.execSQL("ALTER TABLE Done ADD COLUMN 'routineNo' INTEGER")
            }
        }
    }

 

이렇게 Migration을 하고 앱을 실행하면 테이블이 변경되어 있는 것을 확인할 수 있다.

나는 테이블을 추가할 때 Boolean 타입을 넣는 과정에서 Integer로 변환해야 하는 것을 몰라서 헤맸다😶‍🌫️

 


reference >

 

728x90