[Android] 로컬 Database Room 사용하기
업데이트:
🐋 Andorid Database Room 🐬
앱 내부에 로컬 데이터베이스를 이용하여 데이터를 저장하고 관리하는 방법으로 Room 이 있다. 안드로이드 developers 확인해보면 기존에 사용하던 SQLite에서 Room 라이브러리를 사용하라고 권장하고 있다.
Room 라이브러리는 SQLite를 완벽히 활용하면서 원활한 데이터베이스 액세스가 가능하도록 SQLite에 추상화 계층을 제공한다.
Room 라이브러리를 활용해서 오늘 할 일을 추가하는 예제를 만들어보겠다!
📍 Room 사용시 이점
- SQL 쿼리의 컴파일 시간 확인
- 반복적이고 오류가 발생하기 쉬운 상용구 코드를 최소화하는 편의 주석
- 간소화된 데이터베이스 이전 경로
📍 build.gradle 환경 설정하기
- dependency 추가
- kotlin을 사용할 경우 annotationProcessor 대신 kapt 사용
dependencies {
implementation 'androidx.room:room-runtime:2.5.0'
kapt 'androidx.room:room-compiler:2.5.0' // annotationProcessor
}
- kapt 사용을 위해 plugin 추가
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
📍 Room 구성요소
- Database : 데이터베이스를 생성하고 데이터와 기본 연결을 위한 추상 클래스
- Entity : 데이터베이스 테이블
- DAO(Data Access Object) : 앱이 데이터베이스의 데이터에 접근할 수 있는 메소드를 정의해놓은 인터페이스
📍 Entity 정의
- 데이터베이스의 테이블 정보를 정의
@Entity
어노테이션 설정- 테이블이름은 클래스 네임이 default 값이니 따로 지정안해도 된다
- 1개 이상의 식별할 수 있는 PrimaryKey 필요 (
@PrimaryKey
어노테이션 사용) - autoGenerate = true 로 할 경우 key값 자동 생성
@Entity(tableName = "table_todo")
data class TodoEntity(var title: String) {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
}
📍 DAO 정의
- Room 에서는 데이터베이스에 직접 접근하지 않고, DAO 객체를 정의하여 접근
- interface 혹은 Abstract class 로 정의
@Dao
어노테이션 설정- 추가, 업데이트, 삭제 기능을 작성함!
@Dao
interface TodoDAO {
@Query("SELECT * FROM table_todo")
fun getAll(): List<TodoEntity>
@Insert
fun insertTodo(todo: TodoEntity)
@Update
fun updateTodo(todo: TodoEntity)
@Delete
fun deleteTodo(todo : TodoEntity)
}
📍 Database 클래스 정의
- 실제 데이터베이스에 연결을 위한 액세스 포인트!
@Database
어노테이션 설정- Entity의 구조 변경을 해야 할 때 이전과 구분해주기 위해 version을 관리
- 서로 다른 스레드에서 데이터베이스를 한 번에 접근하는 것을 막기 위해 동기화 작업 필요
- 데이터베이스 작업은 Main Thread 작동을 허용하지 않고 있다.
- 그래서 Coroutine 사용해보자
@Database(entities = [TodoEntity::class], version = 1)
abstract class TodoDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDAO
companion object {
private var instance: TodoDatabase? = null
@Synchronized
fun getInstance(context: Context): TodoDatabase? {
if (instance == null)
synchronized(TodoDatabase::class) {
instance = Room.databaseBuilder(
context.applicationContext,
TodoDatabase::class.java,
"todo.db"
).build()
}
return instance
}
}
📍 Database 사용하기
- Todo 내용을 적은 후 추가버튼을 누르면 데이터를 화면에 뿌려주는 기능을 구현해보았다.
db = TodoDatabase.getInstance(this)
CoroutineScope(Dispatchers.IO).launch { // 코루틴 사용 비동기로 실행
binding.resultTextview.text = db!!.todoDao().getAll().toString()
}
binding.addButton.setOnClickListener {
CoroutineScope(Dispatchers.Main).launch {
val temp: Deferred<Boolean> = async(Dispatchers.IO) {
db!!.todoDao().insertTodo(TodoEntity(binding.todoEdittext.text.toString()))
binding.resultTextview.text = db!!.todoDao().getAll().toString()
true
}
temp.await()
}
}
📍 예제 화면
해당 프로젝트 Github 예제는 여기에 😊
sample-room-kotlin
[참고]
https://developer.android.com/training/data-storage/room?hl=ko
모던 안드로이드 - 코틀린과 Jetpack 활용
https://velog.io/@soyoung-dev/AndroidKotlin-ROOM-Database-사용하기