ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Room Database
    Android 2021. 6. 14. 14:25

    안드로이드 아키텍처 컴포넌트에 속하는 Room 라이브러리는 SQLite에 대한 추상화 레이어를 제공하여 원활한 데이터베이스 액세스를 지원하는 동시에 SQLite를 완벽히 활용한다. 

     

    build.gradle 파일에 다음 dependencies를 추가한다. (Kotlin 사용시)

    dependencies {
      def room_version = "2.3.0"
    
      implementation "androidx.room:room-runtime:$room_version"
    
      // To use Kotlin annotation processing tool (kapt)
      kapt "androidx.room:room-compiler:$room_version"
      // To use Kotlin Symbolic Processing (KSP)
      ksp "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"
    }

    Room 주요 구성요소

    룸 데이터베이스(Room Database) : 데이터베이스를 보유하고 앱의 지속적인 관계형 데이터의 기본 연결을 위한 기본 액세스 포인트 역할을 하는 데이터베이스 클래스이다.

    데이터 접근 객체(Data Access Object) : 데이터베이스에 접근하여 수행할 작업을 메소드 형태로 정의한다.

    엔티티(Entity) : 데이터베이스 내의 테이블, DB에 저장할 데이터 형식을 정의한다.

     

    앱은 Room 데이터베이스를 사용하여 데이터베이스와 연결된 데이터 액세스 개체 또는 DAO를 가져온다. 그런 다음 앱은 각 DAO를 사용하여 데이터베이스에서 항목을 가져오고 항목의 변경사항을 다시 데이터베이스에 저장한다. 마지막으로 앱은 항목을 사용하여 데이터베이스 내의 테이블 열에 해당하는 값을 가져오고 설정한다.

     

    간단한 예제 구현하기

    Entity

    @Entity
    class BookInfoEntity (
            val authors:Array<String>?,
            @ColumnInfo(collate = ColumnInfo.NOCASE) val title: String,
            val contents: String?,
            val datetime: String?,
            @PrimaryKey @ColumnInfo(name="isbn") val isbn:String,
            val price:Int?,
            val publisher:String?,
            @SerializedName("sale_price") val salePrice:Int?,
            val status:String?,
            val thumbnail:String?,
            val url:String?,
    ) : Serializable

    @Entity 어노테이션과 함께 데이터베이스 내의 릴레이션을 생성, 하나 이상의 필드를 기본 키로 정의해야 한다. 필드가 하나만 있는 경우에도 @PrimaryKey 주석을 사용하여 필드에 주석을 달아야 합니다. 또한 Room에서 항목에 자동 ID를 할당하게 하려면 @PrimaryKey autoGenerate 속성을 설정하면 된다. 항목에 복합 기본 키가 있으면 @Entity 주석의 primaryKeys 속성을 사용할 수 있다.

     

    기본적으로 Room은 클래스 이름을 데이터베이스 테이블 이름으로 사용하는데 테이블의 이름을 다르게 지정하려면 @Entity 주석의 tableName 속성을 설정하자

    @Entity(tableName = "bookinfo")
    class BookInfoEntity (
     ...
    ) 

    Dao(Data Access Object)

    @Dao 어노테이션과 함께 데이터베이스에 접근하여 수행할 작업들을 메서드 형태로 지정한다. 이 메소드들은 interface 내에 포함되므로 모두 추상 메소드들이다. 쿼리 빌더 또는 직접 쿼리 대신 DAO 클래스를 사용하여 데이터베이스에 액세스하면 데이터베이스 아키텍처의 다양한 구성요소를 분리할 수 있다.

     

    DAO 메서드를 만들고 @Insert 주석을 달 때 Room은 단일 트랜잭션으로 모든 매개변수를 데이터베이스에 삽입하는 구현을 생성한다. onConflict 설정을 통해 만약 데이터베이스 내에 중복된 투플 값이 존재함에도 불구하고 데이터를 추가한다면 그 값 위에 바로 덮어 씌운다.

    @Dao
    interface BookInfoDao{
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun add(info:BookInfoEntity)
        ...
    }

    Update 편의 메서드는 매개변수로 제공된 항목 세트를 데이터베이스에서 수정한다. 이 메서드는 각 항목의 기본 키와 일치하는 쿼리를 사용한다.

    @Dao
    interface BookInfoDao{
        @Update
        fun update(bookinfo: BookInfoEntity)
        ...
    }

    Delete 편의 메서드는 매개변수로 제공된 항목 세트를 데이터베이스에서 삭제한다. 이 메서드는 기본 키를 사용하여 삭제할 항목을 찾는다.

    @Dao
    interface BookInfoDao{
        @Delete
        fun delete(bookinfo: BookInfoEntity)
        ...
    }

    @Query는 DAO 클래스에서 사용하는 기본 주석으로 데이터베이스에서 읽기/쓰기 작업을 실행할 수 있다. 각 @Query 메서드는 컴파일 시간에 확인되므로 쿼리에 문제가 있으면 런타임 오류 대신 컴파일 오류가 발생한다.

    @Dao
    interface BookInfoDao{   
        @Query("SELECT * FROM bookinfo")
        fun getAllBookList(): Flowable<List<BookInfoEntity>>    
        ...
    }

    Database

    @Database 어노테이션과 함께 데이터베이스의 전체적인 소유자 역할을 하고 있으며 앞에서 생성한 Entity, DAO 클래스를 통합적으로 묶어 데이터베이스를 생성하거나 버전 관리를 진행한다.

    @Database(entities = arrayOf(BookInfo::class), version = 1)
    @TypeConverters(Converters::class)
    abstract class BookInfoDatabase:RoomDatabase() {
        abstract fun bookInfoDao():BookInfoDao
    }
    @Module
    class LocalDataModule {
    
        @Provides
        @Singleton
        fun provideBookInfoDao(db:BookInfoDatabase):BookInfoDao
                = db.bookInfoDao()
    
        @Provides
        @Singleton
        fun provideDatabase(@Named("appContext")context: Context):BookInfoDatabase
                = Room.databaseBuilder(context,
                    BookInfoDatabase::class.java, "book_info.db").build()
    }

    References

     

    'Android' 카테고리의 다른 글

    Tests App on Android(2) - Robolectric  (0) 2021.07.01
    Tests App on Android(1)  (0) 2021.06.28
    ConstraintLayout(2)  (0) 2021.06.13
    ConstraintLayout(1)  (0) 2021.06.11
    Room And Coroutines  (0) 2021.06.10
Designed by Tistory.