Room Library 동작방식 및 사용해보기
의존성 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apply plugin: 'kotlin-kapt'
...
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
-kapt 란?
“자바 6부터 도입된 Pluggable Annotation Processing 를 Kotlin에서도 사용 가능하게 하는 것” 이라고 공식 문서에 나온다.
여기서 어노테이션 프로세싱이란 우리가 간단하게 ‘@명령어’ 처럼 사용하는 주석 형태의 문자열을 실제 코드로 생성해주는 것이다.
@으로 시작하는 명령어를 어노테이션이라고 하는데, 어노테이션이 컴파일 시에 코드로 생성되기 때문에 실행 시에 발생할 수 있는 성능 문제가 많이 개선된다.
Room 의 3가지 주요 구성요소 Room에는 다음과 같은 세 가지 주요 구성요소가 있습니다.
- 데이터베이스 : 데이터베이스 홀더를 포함하며 앱의 지속적인 관계형 데이터의 기본 연결을 위한 기본 액세스 포인트 역할을 합니다.
@Database로 주석이 지정된 클래스는 다음 조건을 충족해야 합니다.
RoomDatabase를 확장하는 추상 클래스여야 합니다.
주석 내에 데이터베이스와 연결된 항목의 목록을 포함해야 합니다.
인수가 0개이며 @Dao로 주석이 지정된 클래스를 반환하는 추상 메서드를 포함해야 합니다.
런타임 시 Room.databaseBuilder() 또는 Room.inMemoryDatabaseBuilder()를 호출하여 Database 인스턴스를 가져올 수 있습니다. - Entity : 데이터베이스 내의 테이블을 나타냅니다.
- DAO : 데이터베이스에 액세스하는 데 사용되는 메서드가 포함되어 있습니다.
Room 을 사용해 내부 데이터베이스에 저장
- Entity
Entity는 데이터베이스에서 테이블이라고 생각하면 됩니다. 테이블명, 칼럼 명, 칼럼 타입, 기본키, 외래키 등을 정의할 수 있는 annotation들이 있다. - DAO
DAO(Data Access Object)는 데이터베이스에 접근해 CRUD 등을 사용할 수 있게 하는 다양한 annotation들이 있다. -
Database
RoomDatabase 클래스를 상속받는 abstract class 이다. @Database annotation안에 해당 database와 관련된 Entity 리스트를 포함해야 한다. - @Ignore @Ignore 어노테이션을 사용하면 해당 변수가 테입즐과 관계없는 변수라는 정보를 알릴 수 있다.
Todo 앱 예제
- AppDatabase Class
마치 SQLiteOpenHelper를 상속받아서 구현했던 것처럼 Room도 유사한 구조로 사용할 수 있다. Room은 RoomDatabase를 제공하는데 RoomDatabase를 상속받아 클래스를 생성하면 된다.
주의할 점은 추상 클래스로 생성해야 한다는 점이다. 기존 클래스와 동일하게 생성하고 class앞에 abstract 키워드를 붙이면 된다.
- @Database 속성정리
- entities
Room 라이브러리가 사용할 엔터티(테이블) 클래스 목록
- version
데이터베이스의 버전
- exportSchema
true면 스키마 정보를 파일로 출력한다.
1
2
3
4
@Database(entities = [Todo::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDao
}
- Todo Class
Entity Annotation을 사용해 Room에서 사용할 데이터 클래스를 선언해준다.
tablename 옵션을 통해 데이터 베이스 이름을 정해줄 수 있다.
그 외는 클래스명으로 설정된다.1 2 3 4 5 6 7 8
@Entity data class Todo( var title: String ){ //DB 의 AI @PrimaryKey(autoGenerate = true) var id: Int = 0 }
- TodoDao Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14
@Dao interface TodoDao { @Query("SELECT * FROM Todo") fun getAll(): LiveData<List<Todo>> @Insert suspend fun insert(todo: Todo) @Update suspend fun update(todo: Todo) @Delete suspend fun delete(todo: Todo) }
- 이후에 ViewModel 클래스에서 데이터베이스 인스턴스 가져오기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class MainViewModel(application: Application) : AndroidViewModel(application) { private val db = Room.databaseBuilder( application, AppDatabase::class.java, "todo-db" ).build() var todos: LiveData<List<Todo>> var newTodo: String? = null init { todos = getAll() } fun getAll(): LiveData<List<Todo>> { return db.todoDao().getAll() } fun insert(todo: String) { viewModelScope.launch(Dispatchers.IO) { db.todoDao().insert(Todo(todo)) } }
소스코드링크(github)