[ Room ]
- SQLite를 쉽게 사용할 수 있는 데이터베이스 객체 매핑 라이브러리
- 쉽게 Query를 사용할 수 있는 API 를 제공함
- Query 를 컴파일 시간에 검증함
- Query 결과를 LiveData 로 하여 데이터베이스가 변경될 때마다 쉽게 UI를 변경할 수 있음
=> SQLite 보다 Room 을 사용할 것을 권장함
[ Room 주요 3 요소 ]
@Database
클래스를 데이터베이스로 지정하는 annotation, RoomDatabase를 상속받은 클래스여야 함
@Entity
클래스를 테이블 스키마로 지정하는 annotation
@Dao
클래스를 DAO(Data Access Object)로 지정하는 annotation
-> 기본적인 insert, delete, update SQL은 자동으로 만들어 줌, 복잡한 SQL 은 직접 만들 수 있음
[ gradle 파일 설정 ]
- Room 은 안드로이드 아키텍처에 포함되어 있음
- 사용하기 위해 build.gradle 파일의 dependecies 에 내용을 추가해야 함
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
kotlin("kapt")
}
ㄴ> kapt 를 사용하기 위해 plugins 에 관련 내용을 추가해야 함 (버전을 명시해도 되지만 현재 본인이 사용해야 하는 Kotlin 버전에 맞춰서 명시해 줘야 함)
dependencies {
val room_version = "2.6.1"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
testImplementation("androidx.room:room-testing:$room_version")
}
ㄴ> 의존성 추가 부분에는 사용할 room 의 버전 (가능한 최신 버전을 쓰는 것이 좋음) 의 내용과 필요한 다른 것들을 추가하면 된다
[ Entity 생성 ]
- 테이블 스키마 정의
- CREATE TABLE student_table (student_id INTEGER PRIMARY KEY, name TEXT NOT NULL);
- @Entity data class Student
package com.example.roomdatabase.data
import androidx.room.*
@Entity(tableName = "student_table") // 테이블 이름을 student_table로 지정함
data class Student (
@PrimaryKey @ColumnInfo(name = "student_id")
val id: Int,
val name: String
)
[ DAO 생성 ]
- DAO 는 interface 나 abstract class 로 정의되어야 함
- Annotation 에 SQL 쿼리를 정의하고 그 쿼리를 위한 메소드를 선언
- 가능한 annotation 으로 @Insert, @Update, @Delete, @Query 가 있음
@Dao
interface MyDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE) // INSERT, key 충돌이 나면 새 데이터로 교체
suspend fun insertStudent(student: Student)
@Query("SELECT * FROM student_table")
fun getAllStudents(): LiveData<List<Student>> // LiveData<> 사용
@Query("SELECT * FROM student_table WHERE name = :sname")
suspend fun getStudentByName(sname: String): List<Student>
@Delete
suspend fun deleteStudent(student: Student); // primary key is used to find the student
// ...
}
- @Insert, @Update, @Delete는 SQL 쿼리를 작성하지 않아도 컴파일러가 자동으로 생성함
- @Insert나 @Update는 key가 중복되는 경우 처리를 위해 onConflict를 지정할 수 있음
- OnConflictStrategy.ABORT: key 충돌시 종료
- OnConflictStrategy.IGNORE: key 충돌 무시
- OnConflictStrategy.REPLACE: key 충돌시 새로운 데이터로 변경
- @Update나 @Delete는 primary key에 해당되는 튜플을 찾아서 변경/삭제 함
- @Insert나 @Update는 key가 중복되는 경우 처리를 위해 onConflict를 지정할 수 있음
[ Migration ]
앞에서 MyRoomDatabase 객체 생성 후 addMigrations() 메소드를 호출하여 Miagration 방법을 지정함
Room.databaseBuilder(...).addMigrations(MIGRATION_1_2, MIGRATION_2_3)
private val MIGRATION_1_2 = object : Migration(1, 2) { // version 1 -> 2
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE student_table ADD COLUMN last_update INTEGER")
}
}
private val MIGRATION_2_3 = object : Migration(2, 3) { // version 2 -> 3
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE class_table ADD COLUMN last_update INTEGER")
}
}
ㄴ> 여러 개의 Migration 을 지정할 수 있다.
[ UI와 연결 ]
myDao = MyDatabase.getDatabase(this).getMyDao()
runBlocking { // (주의) UI를 블록할 수 있는 DAO 메소드를 UI 스레드에서 바로 호출하면 안됨
myDao.insertStudent(Student(1, "james")) // suspend 지정되어 있음
}
val allStudents = myDao.getAllStudents() // LiveData는 Observer를 통해 비동기적으로 데이터를 가져옴
[ LiveData ]
: 안드로이드 아키텍처 컴포넌트의 일부로 관찰 가능한 데이터 홀더 클래스이며 이를 통해 UI 컴포넌트(ex: 액티비티, 프래그먼트)는 데이터의 변경 사항을 관찰하고 이에 반응함. 데이터가 변경될 때마다 LiveData 는 관찰자에게 알림을 보냄
LiveData의 핵심 특징
- 수명 주기 인식
: 안드로이드의 수명주기를 인식함 액티비티나 프래금먼트의 수명 주기
https://github.com/Yejin-Byun/RoomDataBase.git
'Android' 카테고리의 다른 글
(Android) 의존성 주입(Dependency Injection) 정의 및 예시 + Dagger-Hilt 활용 (1) | 2024.09.02 |
---|---|
(Android) - MVC, MVP, MVI 패턴의 이해 및 장단점 (0) | 2024.08.24 |
(Android) - MVVM 패턴 (ViewModel, LiveData, Observer) (0) | 2024.06.26 |
(Android / Kotlin) - SharedPreferences (2) | 2024.04.30 |
(Android Studio) - Dialog 사용하기 (0) | 2024.04.23 |