본문 바로가기
Android

[Kotlin] 코틀린 안드로이드 ROOM (database) 사용해보기

by bryan.oh 2023. 8. 24.
반응형

Retrofit2 로 받아온 데이터를 ROOM 을 사용해 Database 에 넣기

Retrofit2 에서 사용한 data class 를 ROOM 에서도 사용하는 예제입니다.

Json Serializer 겸, Entity

 

기본적인 ROOM 사용법만 알고 싶다면 아래 글을 확인하시게 좋습니다.

2023.08.24 - [Android] - [Kotlin] 코틀린 Room Database 사용하기. CRUD

 

[Kotlin] 코틀린 Room Database 사용하기. CRUD

Android Kotlin ROOM build.gradle 아래 내용 추가 plugins { id 'kotlin-kapt' } dependencies { def room_version = "2.5.2" implementation "androidx.room:room-runtime:${room_version}" implementation "androidx.room:room-ktx:${room_version}" kapt "androidx.

hello-bryan.tistory.com

 

build.gradle 

다음 항목들 추가.

plugins {
    id 'kotlin-kapt'
}


dependencies {
    def room_version = "2.5.2"

    // room db
    implementation "androidx.room:room-runtime:${room_version}"
    implementation "androidx.room:room-ktx:${room_version}"
    kapt "androidx.room:room-compiler:${room_version}"
}

우측 상단에 sync_now 클릭~!

 

data class 추가

이 data class Entity 로 테이블을 생성합니다.

기존에 휴일api 에서 받아올때 만들었던 PublicHolidays 를 사용하기로 합니다.

테이블에 insert 할 데이터를 받아오려면 아래 링크 참고하세요~
[Android] - [Kotlin] Android 에서 Retrofit2 사용하여 API 호출하기

@Entity 와 @PrimaryKey 를 추가하고, @ColumnInfo 를 사용해서 컬럼 설정을 합니다.

package com.example.test01.models

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
import java.util.Date

@Entity(tableName = "holidays")
data class PublicHolidays(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    @ColumnInfo(name = "date")
    @SerializedName("date")
    val date: Date,
    @ColumnInfo(name = "local_name")
    @SerializedName("localName")
    val dateName: String,
    @SerializedName("name") val engName: String,
    @SerializedName("countryCode") val locale: String,
    @SerializedName("fixed") val fixed: Boolean,
    @SerializedName("global") val global: Boolean,
    @SerializedName("counties") val counties: String?,
    @SerializedName("launchYear") val launchYear: String?,
    @SerializedName("type") val type: String
)

 

DAO 생성

package com.example.test01.repository

import androidx.lifecycle.LiveData
import androidx.room.*
import com.example.test01.models.PublicHolidays

@Dao
interface PublicHolidayDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertHoliday(publicHolidays: PublicHolidays)

    @Delete
    suspend fun deleteHoliday(publicHolidays: PublicHolidays)

    @Query("SELECT * FROM holidays")
    fun getAllHolidays(): LiveData<List<PublicHolidays>>
}

 

Converters 생성

 Date <-> String convert

import androidx.room.TypeConverter
import java.util.*

class Converters {
    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return value?.let { Date(it) }
    }

    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time
    }
}

 

 

Database 생성

singleton 으로 생성

dao 는 추가 될 여기에 추가 (ex: PublicHolidayDao )

@Database(
    entities = [PublicHolidays::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class HolidayDatabase : RoomDatabase() {
    abstract fun publicHolidayDao(): PublicHolidayDao

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

        private fun buildDatabase(context: Context): HolidayDatabase =
            Room.databaseBuilder(
                context.applicationContext,
                HolidayDatabase::class.java,
                "holiday.db"
            ).build()

        fun getInstance(context: Context): HolidayDatabase =
            INSTANCE ?: synchronized(this){
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }
    }
}

 

사용

activity 에서 

// Activity 의 class property 로 선언
lateinit var db: HolidayDatabase
// onCreate 에서 instance 가져옴
db = HolidayDatabase.getInstance(this)

 

Retrofit 으로 PublicHoliday 데이터 받아오면 onResponse 에서

response.body()?.let{
    CoroutineScope(Dispatchers.Main).launch {
        insertPublicHoliday(it)
    }
}

 

insertPublicHoliday() 함수

activity 의 function 으로 작성

 

suspend fun insertPublicHoliday(dataList: List<PublicHolidays>){
    val insertJob = CoroutineScope(Dispatchers.IO).async {
        for(publicHoliday in dataList) {
            val returnValue = db.publicHolidayDao().insertHoliday(publicHoliday)
            println("returnValue = ${returnValue}")
        }
    }
    insertJob.await()
}

 

데이터 조회

 

db = HolidayDatabase.getInstance(this)
val holidays = db.publicHolidayDao().getAllHolidays()
holidays.observe(this) {
    it.forEachIndexed { _, publicHoliday ->
        println("From Database ${publicHoliday.engName} : ${publicHoliday.locale}")
    }
}

 

결과

728x90
반응형

댓글