본문 바로가기

안드로이드/Jetpack

[안드로이드] Room DB

안드로이드 공식문서

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

 

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

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

developer.android.com

 

Room DB

Room DB는 Jetpack의 라이브러리 중 하나이며, 로컬 데이터베이스이다.

 

일반적으로 플랫폼에서는 DB를 서버에 저장하며, 앱에서는 서버에 요청을 하여 데이터를 조회 또는 수정한다.

 

따라서 네트워크가 필수이며, 네트워크가 없다면 DB에 접근할 수 없다.

 

반면에 로컬 DB는 앱에 저장되므로 네트워크가 따로 필요하지 않기 때문에 사용자가 오프라인 상태에서도 콘텐트를 탐색할 수 있다.

 

Room DB는 SQLite를 사용한다.

 

공식문서에서 말하는 Room DB 장점은 다음과 같다.

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

 

Room의 구성요소

1. Database Class : DB를 보유하고 앱의 영구 데이터와의 기본 연결을 위한 기본 액세스 포인트 역할

2. Data Entity : 앱 DB의 테이블

3. Data Access Objects (DAO) : SQL 문으로 DB 데이터에 접근하기 위한 메서드 모음

 

Database Class를 통해 DAO로 데이터에 접근하고, Data Entity를 가져온다.

 

사용 방법

1. build.gradle (Module)

plugins {
    ...
    id 'kotlin-kapt'
}

dependencies {
    implementation 'androidx.room:room-runtime:2.5.0'
    annotationProcessor 'androidx.room:room-compiler:2.5.0'
    kapt 'androidx.room:room-compiler:2.5.0'
}

 

2. DB Class

@Database(entities = [Entitiy::class], version = 1)
abstract class LocalDataBase : RoomDatabase(){
    abstract fun dao(): DAO

    companion object {
        private var INSTANCE: LocalDataBase? = null

        fun getInstance(context: Context): LocalDataBase? {
            if (INSTANCE == null) {
                // 여러 Thread 가 접근하지 못하도록 Synchronized 사용
                synchronized(LocalDataBase::class) {
                    // Room 인스턴스 생성
                    // 데이터 베이스가 갱신될 때 기존의 테이블을 버리고 새로 사용하도록 설정
                    INSTANCE = Room.databaseBuilder(
                        context.applicationContext,
                        LocalDataBase::class.java, "db"
                    )
                        .fallbackToDestructiveMigration()
                        .build()
                }
            }
            
            return INSTANCE
        }
    }
}

 

3. Entitiy

@Entity
data class Entity(
    @PrimaryKey(autoGenerate = true)
    val id : Int = 0,
    val name : String,
    val age : Int
)

 

autoGenerate = true : 기본키 값인 id를 자동으로 설정

 

4. DAO

@Dao
interface DAO {
    @Query("SELECT * FROM entitiy")
    fun getAll(): LiveData<List<Entity>>

    @Query("SELECT * FROM entity WHERE name = :name")
    fun getEntitiy(name: String): LiveData<Entity>

    @Insert
    fun insert(entity: Entity)

    @Query("Delete From entity WHERE id = :id")
    fun delete(id : Int)

    @Query("Delete From entity")
    fun deleteAll()
}

 

DAO에 사용되는 SQL문은 다양하므로 자세한 내용은 안드로이드 공식문서를 참고 바랍니다.

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

 

Room DAO를 사용하여 데이터 액세스  |  Android 개발자  |  Android Developers

Room 라이브러리의 일부인 DAO(데이터 액세스 개체)를 사용하여 데이터베이스 표를 수정하는 방법 알아보기

developer.android.com

 

5. 사용

class ViewModel(application: Application) : AndroidViewModel(application) {
    private val database = LocalDataBase.getInstance(application)!!
    private val dao = database.DAO()

    val data : LiveData<List<Entitiy>> = dao.getAll()

    fun allDelete(){
        try {
            CoroutineScope(Dispatchers.IO).launch {
                dao.deleteAll()
            }
        }
        catch (e: Exception){
        }
    }

    fun delete(id:Int){
        try {
            CoroutineScope(Dispatchers.IO).launch {
                dao.delete(id)
            }
        }
        catch (e: Exception){
        }
    }

    fun insert(entitiy: Entitiy){
        try{
            CoroutineScope(Dispatchers.IO).launch {
                dao.insert(entitiy)
            }
        }
        catch (e : Exception){ }
    }
}

 

Room DB는 기본 스레드에서 데이터베이스 엑세스를 허용하지 않는다.

따라서 비동기식으로 사용하거나, 관찰 가능한 쿼리를 작성해야 한다.

 

getAll()의 경우 LiveData로 관찰 가능한 쿼리를 적용하였으며,

insert 및 delete의 경우 coroutine을 사용하여 비동기식으로 엑세스하였다.

 

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

 

비동기 DAO 쿼리 작성  |  Android 개발자  |  Android Developers

비동기 DAO 쿼리 작성 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 쿼리가 UI를 차단하지 않도록 Room은 기본 스레드에서 데이터베이스 액세스를 허용하지

developer.android.com

 

'안드로이드 > Jetpack' 카테고리의 다른 글

[안드로이드] Navigation Component  (0) 2023.11.29
[안드로이드] Jetpack  (0) 2023.11.24
[안드로이드] ViewModel  (1) 2023.11.24
[안드로이드] LiveData  (1) 2023.11.23
[안드로이드] Databinding  (1) 2023.11.23