Room은 SQLite에 대한 추상화 계층을 제공하여 SQLite의 모든 기능을 활용하면서 쉬운 데이터베이스 접근을 허용한다.
상당한 양의 구조화된 데이터를 처리하는 앱은 데이터를 로컬로 유지하여 대단한 이점을 얻을 수 있습니다
가장 일반적인 사용 사례는 관련 데이터를 캐싱하는 것입니다. 이런 방식으로 기기가 네트워크에 액세스할 수 없을 때 오프라인 상태인 동안에도 사용자가 여전히 콘텐츠를 탐색할 수 있습니다.
나중에 기기가 다시 온라인 상태가 되면 사용자가 시작한 콘텐츠 변경사항이 서버에 동기화됩니다.
Room은 이러한 문제를 자동으로 처리하므로 SQLite 대신 Room을 사용할 것을 적극적으로 권장된다.
의존성 추가.
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
Room의 구성요소
-
DataBase: 데이터베이스 홀더를 포함하며 앱의 지속적인 관계형 데이터의 기본 연결을 위한 기본 액세스 포인트 역할을 합니다.
@Database로 주석이 지정된 클래스는 다음 조건을 충족해야 합니다.
- RoomDatabase를 상속하는 추상 클래스여야 합니다.
- 주석 내에 데이터베이스와 연결된 Entity의 목록을 포함해야 합니다.
- 인자가 0개이며 @Dao로 주석이 지정된 클래스를 반환하는 추상 메서드를 포함해야 합니다.
런타임 시 Room.databaseBuilder() 또는 Room.inMemoryDatabaseBuilder()를 호출하여 Database 인스턴스를 가져올 수 있습니다.
-
Entity : 데이터베이스 내의 테이블을 나타냅니다.
-
DAO: 데이터베이스에 액세스하는 데 사용되는 메서드가 포함되어 있습니다.
앱은 Room 데이터베이스를 사용하여 데이터베이스와 연결된 데이터 액세스 객체 DAO를 가져옵니다.
그런 다음 앱은 각 DAO를 사용하여 데이터베이스에서 Entity 을 가져오고 Entity 의 변경사항을 다시 데이터베이스에 저장합니다. 마지막으로 앱은 Entity 을 사용하여 데이터베이스 내의 테이블 열에 해당하는 값을 가져오고 설정합니다.


간단한 예시
User Entity
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)
User Dao
@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)
}
database
@Database(entities = arrayOf(User::class), version = 1) // 엔터티 항목 지정
abstract class AppDatabase : RoomDatabase() { // 추상 클래스로 생성
abstract fun userDao(): UserDao // 필수 메서드 설정
}
참고: 앱이 단일 프로세스에서 실행되면 AppDatabase 객체를 인스턴스화할 때 싱글톤 디자인 패턴을 따라야 합니다.
각 RoomDatabase 인스턴스는 리소스를 상당히 많이 소비합니다.
그리고 단일 프로세스 내에서 여러 RoomDatabase 인스턴스에 액세스할 필요가 거의 없습니다.
앱이 여러 프로세스에서 실행되면 데이터베이스 빌더 호출에 enableMultiInstanceInvalidation()을 포함합니다.
이렇게 하면 각 프로세스에 AppDatabase 인스턴스가 있을 때 한 프로세스에서 공유 데이터베이스 파일을 무효화할 수 있으며 이 무효화는 다른 프로세스 내의 AppDatabase 인스턴스로 자동 전파됩니다.