배경
- 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에 대해