@TypeConverter

최희창·2022년 6월 15일
0

배경

  • Room DB에는 기본타입만 저장이 가능하기 때문에 기본타입이 아닌 property가 있을 시 그냥 저장하면 에러가 난다.
  • 이때 @TypeConverter를 통해 해결할 수 있다.

Entity

@Entity
data class UserEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0L,
    val name: String,
    val phones: List<String>,
    val address: Address
)

data class Address(
    val value: String,
    val zipcode: Int
)
  • 현재 Entity에는 List와 Address 형태의 프로퍼티가 존재한다.
  • 그래서 List<'String'>과 Address을 String으로 변환 시켜주는 TypeConverter가 필요하다.

TypeConverter

// List<String>을 String으로 변환해줄 TypeConverter
@ProvidedTypeConverter
class StringListTypeConverter(private val gson: Gson) {

    @TypeConverter
    fun listToJson(value: List<String>): String? {
        return gson.toJson(value)
    }

    @TypeConverter
    fun jsonToList(value: String): List<String> {
        return gson.fromJson(value, Array<String>::class.java).toList()
    }
}

//Address를 String으로 변환해줄 TypeConverter
@ProvidedTypeConverter
class AddressTypeConverter(private val gson: Gson) {

    @TypeConverter
    fun listToJson(value: Address): String? {
        return gson.toJson(value)
    }

    @TypeConverter
    fun jsonToList(value: String): Address {
        return gson.fromJson(value, Address::class.java)
    }
}

Database

@Database(entities = [UserEntity::class], version = 1, exportSchema = false)
@TypeConverters(
    value = [
        StringListTypeConverter::class,
        AddressTypeConverter::class
    ]
)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}
    fun provideDatabase(context: Context, gson: Gson): AppDatabase {
        return Room
            .databaseBuilder(context, AppDatabase::class.java, "sample.db")
            .addTypeConverter(StringListTypeConverter(gson))
            .addTypeConverter(AddressTypeConverter(gson))
            .build()
    }

사용 Activity

   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val db = DatabaseModule.provideDatabase(
            this,
            Gson()
        )
        userDao = db.userDao()

        lifecycleScope.launch {
            insertUser()
        }
    }

    private suspend fun insertUser() {
        val user = UserEntity(
            name = "leveloper",
            phones = listOf("010-1234-5678", "010-5678-1234"),
            address = Address(
                value = "서울시 강남구 어딘가",
                zipcode = 12345
            )
        )
        return withContext(Dispatchers.IO) {
            userDao.insertUser(user)
        }
    }

Gson에 대해

profile
heec.choi

0개의 댓글