Room Databae 사용하기

Room 이란

  • 안드로이드에서 앱의 데이터를 저장하는 방법은 크게 파일, 데이터베이스, 프리퍼런스로 나뉜다. 그 중 데이터베이스 프로그래밍을 이용하여 안드로이드 폰에서 DB를 관리하는 오픈소스 SQLite가 있다.
  • Room은 SQLite 를 완벽히 활용하면서 원활한 데이터베이스 액세스가 가능하도록 SQLite에 추상화 계층을 제공한다.

    Room의 좋은 점

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

Room 기본 구성 요소

Room에는 다음 3가지 주요 구성 요소가 있다.

  • Database class : 데이터베이스를 보유하고 앱의 영구 데이터와의 기본 연결을 위한 엑세스 포인트 역할을 한다.
  • Entity : 앱 데이터베이스의 테이블을 나타냅니다.
  • Data Access Objects(DAO) : 앱이 데이터베이스의 데이터를 쿼리, 업데이트, 삽입, 삭제하는 데 사용할 수 있는 메서드를 제공합니다.

Database
데이터베이스를 보유할 AppDatabase 클래스를 정의한다.
AppDatabase는 데이터베이스 구성을 정의하고 영구 데이터에 대한 앱의 기본 액세스 포인트 역할을 한다. Database class는 다음 조건을 충족한다.

  • 클래스에는 데이터베이스와 연결된 데이터 항목을 모두 나열하는 entities배열이 보함된 @Database 주석을 달아야 한다.
  • 클래스는 RoomDatabase를 확장하는 추상 클래스여야 한다.
  • 데이터베이스와 연결된 각 DAO 클래스에서 데이터베이스 클래스는 인수가 0개이고 DAO 클래스의 인스턴스를 반환하는 추상 메서드를 정의해야 한다.
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

사용

  • Entity와 Dao, Database객체를 정의한 후에는 다음 코드를 사용하여 데이터베이스 인스턴스를 만든다.
    val db = Room.databaseBuilder(
                applicationContext,
                AppDatabase::class.java, "database-name"
            ).build()
  • 다음으로 AppDatabase의 추상 메서드를 사용하여 DAO 인스턴스를 가져올 수 있다. 결과적으로 DAO 인스턴스의 메서드를 사용하여 데이터베이스와 상호작용 할 수 있다.
     val userDao = db.userDao()
     val users: List<User> = userDao.getAll()

Room 사용하기

  • build.gradle

    plugins {
    	id 'kotlin-kapt'
    }
    
    dependencies {
    	// ROOM Database 사용
        implementation("androidx.room:room-runtime:2.4.3")
        annotationProcessor("androidx.room:room-compiler:2.4.3")
        kapt("androidx.room:room-compiler:2.4.3")
        implementation("androidx.room:room-ktx:2.4.3")
    }
  • AppDatabase

    @Database(entities = [WordData::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
    
       abstract fun wordDao() : WordDao
    
      companion object{
            private var INSTANCE : AppDatabase? = null
            fun getInstance(context : Context):AppDatabase? {
                if(INSTANCE == null) {
                    synchronized(AppDatabase::class.java){
                        INSTANCE = Room.databaseBuilder(
                            context.applicationContext,
                            AppDatabase::class.java,
                            "app-database.db"
                        ).build()
                    }
                }
                return INSTANCE
            }
        }
    }
  • Entity

    @Parcelize
    @Entity(tableName = "word")
    data class WordData(
        val word : String,
        val mean : String,
        val type : String,
        @PrimaryKey(autoGenerate = true) val id: Int = 0,
    ) : Parcelable
  • DAO

    @Dao
    interface WordDao {
    
      @Query("SELECT * from word ORDER BY id DESC")
      fun getAll() : List<WordData>
    
      @Query("SELECT * from word ORDER BY id DESC LIMIT 1")
      fun getLatestWord() : WordData
    
      @Insert
      fun insert(word : WordData)
    
      @Delete
      fun delete(word : WordData)
    
      @Update
      fun update(word : WordData)
    }

Activity에서 사용

val list = AppDatabase.getInstance(this)?.wordDao()?.getAll() ?: emptyList()
          wordAdapter.itemList.addAll(list)

AppDatabase.getInstance(this)?.wordDao()?.getLatestWord()?.let {word ->
              wordAdapter.itemList.add(0, word)
              runOnUiThread { wordAdapter.notifyDataSetChanged() }
          }

AppDatabase.getInstance(this)?.wordDao()?.insert(item)

AppDatabase.getInstance(this)?.wordDao()?.update(word)

0개의 댓글