[Android Studio] Room DB 사용하기

gyeol·2025년 6월 3일
post-thumbnail

Room Database?

Room은 Android Jetpack의 ORM 라이브러리로 SQLite를 추상화하여 보다 쉽게 데이터베이스에 접근 가능하도록 도와준다.
이를 사용하기 위해서는 @Entity, @DAO, @Database 를 사용해 선언해야 한다.

구성 요소설명
@EntityDB 테이블에 해당하는 데이터 모델 클래스
@DaoSQL 쿼리를 추상화한 인터페이스
@DatabaseRoom DB 전체를 구성하는 클래스

@Entity

데이터베이스 테이블에 해당하는 데이터 모델이다.

@Entity(tableName = "look_note")
data class LookNoteEntity(
    @PrimaryKey val date: String,
    val imageUri: String?,
    val top: String?,
    val bottom: String?,
    val shoes: String?,
    val etc: String?,
    val memo: String?
)

여기서 @Entity는 이 클래스가 데이터베이스 테이블이라는 것을 의미한다.

@DAO

SQL 쿼리를 추상화하여 제공하는 인터페이스이다.

@Dao
interface LookNoteDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(note: LookNoteEntity)

    @Query("SELECT * FROM look_note ORDER BY date DESC")
    suspend fun getAll(): List<LookNoteEntity>

    @Query("SELECT * FROM look_note WHERE date = :date LIMIT 1")
    suspend fun getByDate(date: String): LookNoteEntity?

    @Query("DELETE FROM look_note WHERE date = :date")
    suspend fun deleteByDate(date: String)

    @Query("SELECT * FROM look_note")
    fun getAllFlow(): kotlinx.coroutines.flow.Flow<List<LookNoteEntity>>
}

이런 식으로 데이터베이스에 조회할 쿼리문을 적어준다고 생각하면 편하다.
이때 인터페이스에 코드를 수정하고 다시 build하면 오류가 나는 경우가 있는데, 이때 Clean Project를 해준 뒤, 다시 build를 해주면 잘 돌아가는 경우가 많았다.

@Database

Room DB의 구성 클래스로 Room.databaseBuilder()로 인스턴스를 생성한다.

// 어떤 엔티티를 사용할지 지정해줌
@Database(entities = [LookNoteEntity::class], version = 1)
abstract class LookNoteDB : RoomDatabase() {
	// DAO 인터페이스 연결
    abstract fun lookNoteDao(): LookNoteDao

    companion object {
        @Volatile private var instance: LookNoteDB? = null
		
        // DB 객체가 1개만 생성되도록 하여 앱 전체에서 재사용함 (싱글톤)
        fun getInstance(context: Context): LookNoteDB {
            return instance ?: synchronized(this) {
                instance ?: Room.databaseBuilder(
                    context.applicationContext,
                    LookNoteDB::class.java,
                    "look_note_database"
                ).build().also { instance = it }
            }
        }
    }
}

사용하기

다음과 같이 @Entity, @DAO, @Database를 정의해준 뒤, MainActivity.kt와 같은 데이터베이스를 사용할 코틀린 파일에서 데이터베이스 인스턴스를 정의해준다.

val db = LookNoteDB.getInstance(this)

이후, 우리가 인터페이스에 정의한 메서드들을 사용하려는 메서드를 적어주면 된다.

lifecycleScope.launch {
    val notes = db.lookNoteDao().getAll()
    notes.forEach {
        Log.d("DB확인", "날짜=${it.date}, 이미지=${it.imageUri}")
    }
}

lifecycleScope.launcu {...} 코루틴을 사용해 Room의 함수를 호출하면 된다.

추가

나는 게시판 비슷한 기능을 사용했는데 이때 글을 적고 다시 메인화면으로 가면 데이터베이스에 추가된 내용이 바로바로 반영되지 않는 상황이 발생했는데, 이때 getAllFlow()를 사용해 UI에서 변경 사항을 실시간으로 감지할 수 있도록 하였다.

@Query("SELECT * FROM look_note")
fun getAllFlow(): kotlinx.coroutines.flow.Flow<List<LookNoteEntity>>
lifecycleScope.launch {
    db.lookNoteDao().getAllFlow().collect { notes ->
        // DB 변경이 생길 때마다 자동으로 여기 호출됨
        calendarView.notifyCalendarChanged()
    }
}
profile
공부 기록 공간 '◡'

0개의 댓글