
🎉Room 이란 ?
제가 안드로이드를 맨 처음 공부했을 땐 Local Database로 SQLite를 사용했습니다. 하지만 SQLite만으론 공식문서에서 다음과 같은 문제점을 제시했습니다.

즉, Database에 접근하기 위한 Query를 Database Schema가 변경됨에 따라 사용자가 Query를 수동으로 업데이트 해야 되는데, 이 과정은 시간도 오래 걸리고 오류가 발생할 가능성이 높습니다
Room은 이를 개선해 만든 AAC(Android Architecture Components)로 다음과 같은 역할을 수행합니다.
1. ORM(Object Relational Mapping) Library
Room은 데이터베이스의 테이블과 앱의 객체 사이의 매핑을 자동으로 처리해주는 ORM 라이브러리로 DB Data를 Java 또는 Kotlin 객체로 Mapping 하거나 반대로 Java, Kotlin 객체를 데이터베이스에 저장할 수 있도록 도와줍니다.
2. SQLite 내부 사용 및 구조적 분리
내부적으로 SQLite를 사용하지만 이를 추상화하여 개발자가 직접적으로 SQL Query를 작성하지 않아도 됩니다.
3. Annotation을 사용한 자동 코드 생성
@Entity, @Dao, @Database 등의 어노테이션을 사용하여 데이터베이스 관련 클래스 및 메서드를 정의하면 Room이 필요한 코드를 생성해줍니다.
4. LiveData, StateFlow 및 Observe 지원:
LiveData, StateFlow와 같은 Observe를 지원해 데이터의 변경을 실시간으로 감지해 UI를 업데이트 할 수 있습니다. 또한 Reactive Programming을 지원해 MVP, MVVM 아키텍쳐 패턴에 쉽게 사용할 수 있습니다.
🎉Room의 구조

1️⃣ Entity Class
- Database Table에 저장할 데이터들을 만들니다.
- @Entity(tableName = "") : Table 이름을 설정합니다.
- @Primary : Entity Class들은 반드시 하나의 Primary key를 가져야 합니다.
- @ColumnInfo : Database Table 내에서 Column을 변수와 매칭, defaultValue의 매개변수로 기본값을 설정할 수 있습니다.
@Entity(tableName = "number_table")
data class NumberEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var id : Int = 0,
@ColumnInfo(name = "randomNumber")
var randomNumber : String
)
1️⃣ DAO Class
Data Access Object의 약자로 실제 Database에 접근하여 수행할 작업을 정의합니다.
@insert : Entity Class에 정의한 객체를 전달받아 데이터베이스에 데이터를 추가합니다.
- onConflict : 데이터베이스에 데이터를 삽입할 때, 이미 해당 행이 존재하는 경우 어떻게 처리할지를 지정하는 옵션
- OnConflictStrategy.REPLACE:
- 이미 해당 행이 존재하면 새로운 데이터로 기존 행을 대체합니다.
- OnConflictStrategy.IGNORE:
- 이미 해당 행이 존재하면 삽입을 무시하고 아무 작업도 수행하지 않습니다. 즉, 삽입 시도가 실패해도 예외를 발생시키지 않고 계속 진행됩니다.
- OnConflictStrategy.ABORT:
- 이미 해당 행이 존재하면 삽입을 중단하고 SQLiteConstraintException을 발생시킵니다.
- OnConflictStrategy.FAIL:
- 이미 해당 행이 존재하면 삽입을 실패로 간주하고 SQLiteConstraintException을 발생시킵니다.
- OnConflictStrategy.REPLACE:
@Query : DataBase에서 수행할 Query를 정의합니다. Compile 시에 Return되는 Object의 Field와 Query의 결과로 나오는 Column의 이름이 일치하는지 확인해 match 되는게 없다면 Error를 반환합니다.
@update : Entity Class에 지정된 Primary 값을 기준으로 Table Column을 업데이트합니다.
@delete : Entity Class에 지정된 Primary 값을 기준으로 Table Column을 제거합니다.
@Dao
interface NumberDao {
// CRUD
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun create(numberEntity: NumberEntity)
@Query("SELECT * FROM number_table")
fun read() : Flow<List<NumberEntity>>
@Update
fun update(numberEntity: NumberEntity)
@Delete
fun delete(numberEntity: NumberEntity)
}
3️⃣ Database Class
- @Database(entites = [ EntityClass ], version ) : 데이터 베이스 클래스를 명시하며 Entity Class와 version을 지정해줍니다.
- Database Class는 추상 클래스로 선언되며 RoomDatabase() 클래스를 상속 받습니다.
- 데이터베이스와 연결된 각 DAO 클래스의 인스턴스를 반환하는 추상 메서드를 정의해야 합니다.
- 공식 문서에서는 다음과 같은 이유로 데이터 베이스 객체를 싱글톤으로 구현하기를 권장합니다.

- @Volatile : Java 변수를 메인 메모리에 저장하겠다는 것을 명시하기 위해 사용합니다.
- Volatile 변수를 사용하지 않는 일반 변수의 경우 Task를 수행하는 동안 성능 향상을 위해 메인 메모리에서 읽은 변수 값을 캐시에 저장합니다.
Volatile는 쓰레드의 동기화 문제를 해결하기 위해 사용합니다.
📕쓰레드 동기화 문제
멀티 쓰레드 어플리케이션의 경우 각 쓰레드를 통해 CPU에 캐싱한 값이 서로 다르거나 멀티 쓰레드 간의 변경 사항이 즉시 모든 쓰레드에 적용되지 않을 수 있습니다. 이러한 문제를 해결하기 위해 Volatile 어노테이션을 사용하면 항상 변수를 메인 메모리에서 읽기, 쓰기를 하도록 보장합니다.
예를 들어, 스레드 A에서 변수를 수정하면, 스레드 B에서 해당 변수를 읽을 때 최신의 값이 사용됩니다. 이는 변수에 대한 변경 사항이 모든 쓰레드에게 즉시 반영되어 일관성을 보장 합니다.
- Volatile 변수를 사용하지 않는 일반 변수의 경우 Task를 수행하는 동안 성능 향상을 위해 메인 메모리에서 읽은 변수 값을 캐시에 저장합니다.

- synchronized : 멀티 쓰레드 환경에서 임계 영역을 지정하여 여러 스레드가 동시에 getDatabase를 호출할 때 첫 번째 스레드 만이 synchronized Block에 진입하여 데이터 베이스를 생성하고 INSTANCE 변수에 할당 합니다. 이 때, 다른 쓰레드들은 이 블록에 진입할 때 까지 기다리고 이로 인해 여러 스레드간의 경쟁 상태를 해결할 수 있습니다.
🔨 임계 영역
여러 스레드가 공유 자원에 접근하는 부분 중에서 오직 하나의 스레드만이 접근할 수 있도록 제한된 영역
@Database(entities = [NumberEntity::class], version = 1)
abstract class MyDatabase : RoomDatabase() {
abstract fun numberDao() : NumberDao
companion object {
@Volatile
private var INSTANCE : MyDatabase? = null
fun getDatabase(
context : Context
) : MyDatabase {
return INSTANCE ?: synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
MyDatabase::class.java,
"number_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
instance
}
}
}
}
GitHub - chanho0908/Android-Architecture-Components-Room: Android Architecture Component Room 학습 기록을 위한 Repository
Android Architecture Component Room 학습 기록을 위한 Repository - GitHub - chanho0908/Android-Architecture-Components-Room: Android Architecture Component Room 학습 기록을 위한 Repository
github.com
'Android' 카테고리의 다른 글
[Android] Room Database Migration (1) | 2024.01.21 |
---|---|
[Android] Room TypeConverter (0) | 2024.01.21 |
[Android] Jetpack WorkManager (0) | 2024.01.07 |
[Android]Android Memory Process (1) | 2024.01.07 |
Android Daum 우편번호 서비스 API With FireBase Hosting (2) | 2024.01.04 |