개발린생

[안드로이드/Kotlin] Room 라이브러리 사용 본문

Dev Lab ✧.·˚/Android & iOS

[안드로이드/Kotlin] Room 라이브러리 사용

김블루 2023. 1. 17. 18:37

* 이 포스트에 작성된 코드는 Kotlin 언어로 작성하였습니다.

 

앱 내 간단한 데이터를 다루기 위해서는 주로 SharedPreference를 사용하고

조금 더 복잡한 데이터를 다루기 위해 SQLite Database를 사용합니다.

 

이번에는 SQLite를 직접적으로 다루는 방식이 아닌 SQLite를 활용하는 Room 라이브러리 사용해보고자합니다.


Android Jetpack의 구성요소 Room

Room은 Jetpack의 구성요소 이며, Jetpack은 개발자가 중요한 코드에 집중할 수 있도록 권장사항 준수, 상용구 코드 감소, 여러 Android 버전과 기기에서 일관되게 작동하는 코드 작성을 돕는 라이브러리 묶음입니다.

 

우리는 상당한 양의 구조화된 데이터를 처리하는 앱은 데이터를 로컬에 유지하여 매우 큰 이익을 얻을 수 있습니다. 가장 일반적인 사용 사례는 기기가 네트워크에 액세스할 수 없을 때도 사용자가 오프라인 상태로 계속 콘텐츠를 탐색할 수 있도록 관련 데이터를 캐시하는 것입니다.

 

지속성 라이브러리 Room은 SQLite를 완벽히 활용하면서 원활한 데이터베이스 액세스가 가능하도록 SQLite의 추상화 계층을 제공합니다. 특히 Room을 사용하면 다음과 같은 이점이 있습니다.

 

여러 블로그 포스트를 보며 잘못된 내용도 있는 것을 보아 공식 문서의 내용을 참고하심이 가장 좋을 것 같습니다.

Room을 안드로이드에서 사용하는 DB로 분류 하여 SQLite, Realm 등의 DB라는 식의 해석은 잘못된 해석이라 생각됩니다.

Room은 SQLite를 활용하는 라이브러리 입니다.

 

Room 사용 이점

  • SQL 쿼리의 컴파일 시간 확인
  • 반복적이고 오류가 발생하기 쉬운 상용구 코드를 최소화하는 편의 주석
  • 간소화된 데이터베이스 이전 경로

이러한 점을 고려하여 SQLite를 직접 사용하는 대신 Room 라이브러리를 사용하는 것이 좋습니다.


Room 기본 구성요소

  1. Entity : 데이터베이스 내에 존재하는 테이블을 나타낸 것
  2. DAO (Data Access Objects) : 앱에서 데이터베이스의 데이터에 접근하는데 사용되는 메서드를 제공해주는 역할, 그 외 다양한 쿼리 사용 가능 
  3. Database : 앱에 저장된 로컬 데이터에 대한 액세스 포인트를 제공해주는 역할

Room 라이브러리 사용하기

라이브러리 추가

Kotlin에서 kapt 컴파일러 플러그인과 함께 사용하도록 되어있기 때문에 아래와 같은 플러그인도 추가해야합니다.

plugins {
    ...
    id 'kotlin-kapt'
}
dependencies {
	...
    /* room */
    implementation 'androidx.room:room-runtime:2.4.0'
    kapt 'androidx.room:room-compiler:2.4.0'
}

 

Entity data class 생성

해당 @Entity는 tableName 속성에 테이블명 값을 지정함으로 MemoEntity가 아닌 Memo 테이블명을 가진다.

id는 @PrimaryKey로 기본 키로 정의되며 autoGenerate 속성으로 인해 값이 자동으로 할당된다.

regDate, modDate는 @ColumnInfo name 속성에 컬럼명 값을 입력하므로 reg_date, mod_date 컬럼명을 가진다.

@Entity(tableName = "Memo")
data class MemoEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long? = null,
    val title: String,
    val content: String,
    @ColumnInfo(name = "reg_date") val regDate: Long = System.currentTimeMillis(),
    @ColumnInfo(name = "mod_date") val modDate: Long = System.currentTimeMillis()
)

 

DAO interface 생성

해당 interface 에서는 실행할 쿼리를 메서드로 만들어두고 사용한다.

selectKeyword 메서드의 경우, keyword 매개변수 값을 쿼리에 적용하기 위해 :keyword 를 입력하여 사용한다.

@Dao
interface MemoDao : BaseDao<MemoEntity> {
    @Query("SELECT * FROM Memo ORDER BY mod_date DESC")
    fun selectAll(): List<MemoEntity>

    @Query("SELECT * FROM Memo WHERE title LIKE '%' || :keyword || '%' OR content LIKE '%' || :keyword || '%' ORDER BY mod_date DESC")
    fun selectKeyword(keyword: String): List<MemoEntity>
}

 

Database class 생성

필요한 entity 배열과 데이터베이스 버전을 어노테이션 안에 포함한다.

@Database(entities = [MemoEntity::class], version = 1, exportSchema = false)
abstract class RoomHelper: RoomDatabase() {
    abstract fun memoDao(): MemoDao
}

 

사용 예시 코드

private val memoDao by lazy {
    Room.databaseBuilder(this, RoomHelper::class.java, "memo_db")
        .allowMainThreadQueries()
        .build()
        .memoDao()
}
/* insert */
memoDao.insert(
    MemoEntity(
        title = title,
        content = content
    )
)
/* update */
memoDao.update(
    MemoEntity(
        id = it.id,
        title = title,
        content = content,
        modDate = System.currentTimeMillis(),
        regDate = it.regDate
    )
)
val adapter = ListAdapter()
adapter.items = /* select */ memoDao.selectAll()
adapter.listener = this@MainActivity
recyclerView.adapter = adapter

 

예제와 함께 쉬운 이해를 위해 기술블로그로 학습하는 것도 좋으나

정확한 정보를 위해서는 공식 사이트의 내용을 참고하는 것을 추천드립니다.

 

 

https://developer.android.com/topic/libraries/architecture/room?hl=ko 

 

Room 지속성 라이브러리  |  Android 개발자  |  Android Developers

Room 라이브러리 사용 방법을 알아봅니다.

developer.android.com

https://developer.android.com/training/data-storage/room?hl=ko 

 

Room을 사용하여 로컬 데이터베이스에 데이터 저장  |  Android 개발자  |  Android Developers

Room 라이브러리를 사용하여 더 쉽게 데이터를 유지하는 방법 알아보기

developer.android.com