posite 2026. 2. 21. 14:51

Room

  • SQLite Database를 더 쉽고 안전하게 사용할 수 있도록 감싼 Jetpack 라이브러리로 관계형 DB이다.
  • 컴파일 타임에 SQL 쿼리를 검사하여 안정적이다.
  • LiveData, Flow, Paging 등 다른 Jetpack 라이브러리와 호환성이 높다.
  • Entity, DAO, DB로 이루어져 있으며, Entity에서 data class로 table을 구성, DAO에서 수행할 연산 구성, DB에서 Database를 생성한다.
  • SQLite에 없는 type의 요소를 Entity에 정의할 경우, TypeConverter를 구현 후, DB에 @TypeConverters 어노테이션에 넣어주어야 한다.
  • DAO는 interface로 작성하며, @DAO 어노테이션이 필요하다. 연산을 직접 구현하지 않고 Update, Insert 등의 어노테이션을 퉁해 수행할 작업을 선언한다. Select, 복잡한 작업의 경우 @Query 어노테이션을 통해 직접 SQL문을 작성할 수 있다.
  • DB 생성 후, Entity 구성의 변화가 생길 경우, DB의 @Database 어노테이션 안의 버전을 증가시켜주어야 한다.
@Parcelize
@Entity(tableName = "wish_table")
data class WishEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0L,
    val title: String,
    val description: String,
    val date: Date
) : Parcelable {
    companion object {
        fun getEmpty() = WishEntity(0L, "", "", Date())
    }
}

class DateConverter {
    @TypeConverter
    fun dateToString(date: Date): String {
        return date.time.toString()
    }

    @TypeConverter
    fun stringToDate(value: String): Date {
        return Date(value.toLong())
    }
}
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.posite.modern.data.local.entity.WishEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface WishDao {
    @Insert(onConflict = OnConflictStrategy.ABORT)
    suspend fun addWish(wish: WishEntity)

    @Query("SELECT * FROM  wish_table")
    fun getAllWishes(): Flow<List<WishEntity>>

    @Query("SELECT * FROM wish_table WHERE id = :id")
    fun getWishById(id: Long): Flow<WishEntity>

    @Update
    suspend fun updateWish(wish: WishEntity)

    @Delete
    suspend fun deleteWish(wish: WishEntity)
}
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.posite.modern.data.local.dao.WishDao
import com.posite.modern.data.local.entity.DateConverter
import com.posite.modern.data.local.entity.WishEntity

@Database(
    entities = [WishEntity::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(DateConverter::class)
abstract class WishDB : RoomDatabase() {
    abstract fun wishDao(): WishDao
    companion object{
        private var instance : MemoDB? = null

        @Synchronized
        fun getInstance(context: Context) : MemoDB? {
            if (instance == null){
                synchronized(WishDB::class){
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        WishDB::class.java,
                        "wish_db"
                    ).fallbackToDestructiveMigration().build()
                }
            }
            return  instance
        }
    }
}