Android

[Android] Room TypeConverter

빨주노초잠만보 2024. 1. 21. 19:29

 

📕 Room의 Type 제한

Room에 데이터를 저장할 때 원시 타입( char, int, short, long, float...)과 Wrapping Type만 지원합니다.

그 이유로 공식문서는 다음과 같이 이유를 설명 합니다.



  • 효율성 및 성능
     원시 타입과 래핑 타입은 메모리 사용 및 연산 효율성이 더 뛰어나기 때문에 데이터베이스 작업 시 성능을 최적화할 수 있어 객체가 아닌 기본 타입을 사용함으로써 메모리 소비가 감소하고, 데이터베이스 연산이 빨라집니다.

    Room에서 사용자가 정의한 클래스나 다른 복잡한 타입을 사용하려면 TypeConverter를 사용해 변환해 주어야 합니다.
 

Room을 사용하여 복잡한 데이터 참조  |  Android 개발자  |  Android Developers

Room을 사용하여 복잡한 데이터 참조 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Room은 기본 유형과 박싱된 유형 간 변환을 위한 기능을 제공하지만 항목

developer.android.com

 

 

📕 다양한 Type 사용하기

1️⃣ Date Type

class MyConverters {

    @TypeConverter
    fun fromTimestampToDate(value : Long) : Date {
        return Date(value)
    }

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

 

2️⃣ BitmapImage

class MyConverters {
    @TypeConverter
    fun fromBitmapToByteArray(bitmap: Bitmap) : ByteArray {
        val outputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
        return outputStream.toByteArray()

    }

    @TypeConverter
    fun fromByteArrayToBitmap(byteArray: ByteArray) : Bitmap {
        return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
    }
}

 

3️⃣ Object List

class MyConverters {
	@TypeConverter
    fun listToJson(list: MutableList<TextEntity>): String{
        return Gson.toJson(list)
    }

    @TypeConverter
    fun jsonToList(value: String): MutableList<TextEntity>{
        return Gson.fromJson(value, Array<TextEntity>::class.java).toMutableLust()
    }
}

 

TypeConverter Class를 생성했다면 Database Class에 @TypeConveters 어노테이션의 매개변수로 TypeConverer Class를 전달해주면 원하는 타입의 데이터를 데이터베이스에 저장할 수 있습니다.

import android.content.Context
import androidx.room.*
@Database(
    entities = [TextEntity::class],
    version = 1
)

@TypeConverters(MyConverters::class)
abstract class TextDatabase : RoomDatabase(){

    abstract fun textDao() : TextDao

    companion object {

        @Volatile
        private var INSTANCE : TextDatabase? = null

        fun getDatabase(
            context: Context
        ) : TextDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    TextDatabase::class.java,
                    "text_database"
                )
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                instance
            }
        }

    }


}