앱에서 기능을 추가하고 변경하는 경우 Room 항목 클래스와 기본 데이터베이스 테이블을 수정하여 이러한 변경사항을 반영해야 합니다. 앱 업데이트로 인해 데이터베이스 스키마가 변경될 때는 기기 내 데이터베이스에 있는 사용자 데이터를 유지하는 것이 중요합니다.
https://developer.android.com/studio/inspect/database?utm_source=android-studio
안드로이드 디벨로퍼에서 room DB사용에서 강조하는 내용은 바로 앱 업데이트로 인한 db의 변화에서도 기존의 내부 데이터들이 온전하게 유지되어야 한다는 점이다. 때문에 Migration에 대한 대비가 되어있어야 한다.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
kotlin-kapt
가 plugin에 있다는 가정 하에
defaultconfig
내에
kapt{
arguments{
arg("room.schemaLocation" , "$projectDir/schemas")
}
}
위 내용을 포함시켜준다. gradle sync를 하고, Project로 보기 방식을 바꾸면
app 내의 schemas 폴더가 만들어진 것을 볼 수 있고, 여기 안에
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "6d260d58aa8d20b5eeb6ae71f3a68c8b",
"entities": [
{
"tableName": "student_info",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_name` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "student_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "student_name",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"student_id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6d260d58aa8d20b5eeb6ae71f3a68c8b')"
]
}
}
우리가 작성한 엔티티의 스키마가 생성된 것을 볼 수 있다.
이전에 생성한 Student Entity를 보자
@Entity(tableName = "student_info")
data class Student(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "student_id")
val id : Int,
@ColumnInfo(name = "student_name")
var name : String
)
이렇게 만든 개체에 값을 넣은 다음, entitiy에 이메일도 넣고 싶어 변경을 해보았다.
@Entity(tableName = "student_info")
data class Student(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "student_id")
val id : Int,
@ColumnInfo(name = "student_name")
var name : String,
@ColumnInfo(name = "student_email")
var email: String
)
@Database(entities = [Student::class], version = 1)
abstract class StudentDatabase : RoomDatabase() {
abstract val subscriberDAO: StudentDAO
companion object {
@Volatile
private var INSTANCE: StudentDatabase? = null
fun getInstance(context: Context): StudentDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
StudentDatabase::class.java,
"student_data_database"
).build()
INSTANCE = instance
}
return instance
}
}
}
}
기존의 데이터베이스 파일이다. 여기서
@Database(entities = [Student::class], version = 1)
버전을 바꿔주어
@Database(
entities = [Student::class],
version = 2,
autoMigrations = [AutoMigration(from = 1, to = 2)]
)
위처럼 작성해준다.
이후 build를 새로 하면 project의 schema 폴더에 json 스키마 파일이 추가되면서 새로운 데이터를 이어서 넣을 수 있다.