AAC - Room

Updated:

AAC - Room

Room 은 SQLite에 대한 추상화 레이어를 제공하여 원활한 데이터베이스 액세스를 지원하는 동시에 SQLite 를 완벽히 활용한다.

Room 은 구글에서 만든 공식 ORM(Object-relational mapping) 이라고 할 수 있으며 여러가지 강력한 기능들을 지원한다.

이미지 출처 : https://developer.android.com/training/data-storage/room?hl=ko

Room 은 아래의 3가지 구성요소를 가진다.

  • Database
    • Database Holder 를 포함하여 앱의 지속적인 관계형 데이터의 기본 연결을 위한 기본 액세스 포인트 역할을 한다.
    • Database 로 annotation 이 된 class 는 다음 조건을 충족하여야한다.
      • RoomDatabase 를 확장하는 추상 클래스여야한다.
      • 주석 내에 database 와 연결된 항목의 목록을 포함해야한다.
      • argument 가 0개여야하며, @Dao 로 지정된 클래스를 return 하는 abstract method 를 포함해야한다.
  • Entity
    • database 내의 테이블을 나타낸다.
  • DAO(Data Access Object)
    • database 에 access 하는 데 사용되는 메서드가 포함되어 있다.

사용을 위해서는 module 수준의 gradle 에 room 라이브러리를 추가해준다.

dependencies {
  def room_version = "2.2.5"

  implementation "androidx.room:room-runtime:$room_version"
  kapt "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"
}

DataBase

RoomDatabase 인스턴스를 만드는 과정은 매우 비싼 작업이지만 접근을 자주하게된다. 그렇기에 공식 문서에서는

Database instance 는 singleton 패턴을 이용하여 만드는 것을 권장한다.

공식 문서 발췌

@Database annotation 을 이요하여 사용할 Entity 를 배열로 반드시 입력해야하며, Dao 또한 RoomDatabase 에서 관리 권한을 위임하여 직접적으로 접근을 막아야한다.

@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

//위의 파일을 생성한 후 다음 코드를 사용하여 생성한 Database instance 를 가져오게 된다.

val db = Room.databaseBuilder(
  applicationContext,
  AppDatabase::class.java, "database-name"
).build()

Dao

@Dao Annotation 을 활용하며, interface, abstract class 로 작성해야한다.

query 구문 또한 Annotation 으로 작성 되어야하며, 자동완성을 지원한다.

Room 에서는 SQL 을 이용한 직접적인 쿼리 접근 대신에 DAO 를 이용하여 DB 에 접근해야한다.

@Insert @Update @Delete @Query 와 같은 annotation 을 붙여서 원하는 기능들을 수행할 수 있다.

@Dao
interface UserDao {
  @Query("SELECT * FROM user")
  fun getAll(): List<User>
  
  @Query("SELECT * FROM user WHERE uid IN (:userIds)")
  fun loadAllByIds(userIds: IntArray): List<User>

  @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
         "last_name LIKE :last LIMIT 1")
  fun findByName(first: String, last: String): User

  @Insert
  fun insertAll(vararg users: User)

  @Delete
  fun delete(user: User)
}

Entity

데이터 베이스에 서 테이블과 같은 역할.

@Entity(tableName = “테이블 이름”) 와 같이 이름을 별도로 지정할 수 있지만, 지정하지 않을 경우 default 값으로 class 의 이름이 지정되며 대소문자를 구분하지 않는다.

@PrimaryKey 로 PK 값을 지정할 수 있고 중복시 오류가 발생한다.

autoGenerate = true 를 통하여 자동으로 Key 값을 생성할 수 있다.

@ColumnInfo 로 컬럼명을 지정할 수 있다.

@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)

참고

https://medium.com/@gus0000123/mvvm-aac-room%EC%82%AC%EC%9A%A9%EB%B2%95-1-%EA%B0%9C%EB%85%90%ED%8E%B8-59ad680ea6fe

https://medium.com/@gus0000123/mvvm-aac-room-%EC%82%AC%EC%9A%A9%EB%B2%95-2-%EC%82%AC%EC%9A%A9%ED%8E%B8-43ea8a936b12

https://woovictory.github.io/2019/01/31/Android-AAC-Room/

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

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