프로젝트 메모앱, Room Database클래스 작성

윤재환·2024년 11월 28일
0

Room Datebase 클래스 작성

@Database(
    entities = [
        Memo::class,
        MemoCategory::class,
        Cart::class,
        CartList::class,
        ToDoList::class
    ],
    version = 1,
    exportSchema = false //스키마를 파일로 내보내지 않도록 설정
)
abstract class AppDatabase : RoomDatabase() {

    // DAO를 정의
    abstract fun memoDao(): MemoDao
    abstract fun memoCategoryDao(): MemoCategoryDao
    abstract fun cartDao(): CartDao
    abstract fun cartListDao(): CartListDao
    abstract fun toDoListDao(): ToDoListDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: android.content.Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = androidx.room.Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database" // 데이터베이스 이름
                ).fallbackToDestructiveMigration() // 스키마 변경 시 기존 데이터를 제거
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}

해당 코드를 설명하겠습니다.

1.@Datavase 어노테이션

  • entities: Room에서 관리할 테이블 목록을 지정.
  • version : 데이터베이스 버전.
  • exportSchema: Room이 데이터베이스 스키마를 파일로 내보낼지 여부를 설정, 보통 개발 초기 단계에서는 false로 설정합니다.

  1. Dao연결
abstract fun memoDao(): MemoDao
abstract fun memoCategoryDao(): MemoCategoryDao
abstract fun cartDao(): CartDao
abstract fun cartListDao(): CartListDao
abstract fun toDoListDao(): ToDoListDao

각 dao를 연결해줍니다.
만약 새로운 entity나 dao를 추가시 여기에도 꼭 추가해 줍시다.


  1. 싱글톤 패턴

해당 부분은 잘 모르는 부분이 많았었기에 추가 설명을 하겠습니다.

Room데이터베이스는 앱 전체에서 하나이 인스턴스만 생성하여 사용하는 것이 권장됩니다.
이는 데이터베이스 작업에 매우 비용이 크기 때문입니다.

싱글톤 패턴을 사용하는 이유

  • 비용 효율성
    • 데이터베이스 객체는 생성 비용이 높습니다. 여러 개의 인스턴스를 생성하면 메모리 낭비와 성능 저하가 있을수 있습니다.
    • room database는 내부적으로 스레드 풀을 관리하기 때문에 단일 인스턴스를 유지하는 것이 더 효율 적입니다,.

전체 코드

 companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: android.content.Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = androidx.room.Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database" // 데이터베이스 이름
                ).fallbackToDestructiveMigration() // 스키마 변경 시 기존 데이터를 제거
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }

3.1 @Volatile키워드

@Volatile
        private var INSTANCE: AppDatabase? = null
  • Volatile는 변수의 변경이 모든 스레드에 즉시 반영되도록 보장합니다.
  • Room Database는 멀티스레드 환경에서 사용되므로, 인스턴스 생성시 중복 생성을 방지하기 위해 사용됩니다.
  • 한스레드에서 INSTANCE를 변경하면, 다른 스레드에서도 변경된 값을 즉시 볼 수 있습니다.

3.2 synchronized 블록

return INSTANCE ?: synchronized(this) {
    val instance = Room.databaseBuilder(
        context.applicationContext,
        AppDatabase::class.java,
        "app_database"
    ).fallbackToDestructiveMigration()
     .build()
    INSTANCE = instance
    instance
}
  • synchroized는 여러 스레드가 동시에 접근할 때, 한번에 하나의 스레드만 블록 내부 코드를 실행하도록 보장합니다.
  • 앱이 여러 스레드에서 getInstance를 호출하더라도, 데이터베이스 인스턴스를 중복 생성하지 않습니다.

3.3 Room.databaseBuilder

Room.databaseBuilder(
    context.applicationContext,
    AppDatabase::class.java,
    "app_database"
)
  • Room Database를 빌드하는 메서드 입니다.

  • 매게변수

    • context.applicationContext: 앱의 전체 생명 주기 동안 사용할 Context
    • AppDatabsse::class.java Room Database의 클래스 타입
    • "app-database": 데이터베이스 이름

3.4 fallbackToDestructiveMigration

  • 스키마 변경()이 발생했을 때, 기존 데이터를 삭제하고 새로운 스키마를 적용합니다.
  • 초기 개발 단계에서는 마이그레이션 로직을 작성하는 대신 데이터를 삭제하고 새로 생성하는게 반편합니다.
  • 주의: 나중에 기존 데이터를 유지할려면(예: 완성 버전이후 패치할시) 마이그레이션 로직을 작성해야합니다.

3.5 결과반환

INSTANCE = instance
instance
  • 데이터베이스를 생성한 후, 싱글톤 인스턴스로 저장(INSTANCE = instance)하고 반환합니다.

작동방식

  1. 최초 호출:
    • INSTANCEnull이면 synchronized 블록이 실행됩니다.
    • Room Database를 생성하고 INSTANCE에 저장한 후 반환합니다.
  2. 이후 호출:
    • INSTANCE가 이미 생성되어 있으면 즉시 반환합니다.
    • synchronized 블록은 실행되지 않습니다.
profile
백엔드 개발에 관심있는 1인

0개의 댓글