+10

[Android] TypeConverter Annotation trong Room Database

Trong bài này mình sẽ hướng dẫn anh em setup @TypeConverter trong Room database

1. Room database là gì?

The Room persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.

Room là một persistence library, một phần của Android Architecture Components. Nó giúp bạn dễ dàng là việc với đối tượng SQLiteDatabase trong ứng dụng của bạn hơn, giảm số lượng mã soạn sẵn và xác minh các truy vấn SQL tại thời điểm biên dịch.

Trước khi Room được ra mắt, chúng ta phải viết rất nhiều dòng lệnh phức tạp, dài loằng ngoằng, cơ bản là rất tốn thời gian để setup SQLite 😦 . Room xuất hiện như một vị cứu tinh giúp đỡ anh em, từng câu lệnh, từng query cực kì đơn giản và dễ hiểu. Room cung cấp rất nhiều function, hỗ trợ lưu trữ các dữ liệu nguyên thủy nhưng nó không hỗ trợ các Class Object cho người dùng tự định nghĩa. Tuy nhiên các bạn không phải lo lắng về điều này. TypeConverter lại xuất hiện để cứu anh em. TypeConverter có thể convert một Custom Class sang kiểu dữ liệu mà Room có thể lưu trữ được và ngược lại.

2. Cài đặt

@Entity(tableName = "current_weather")
data class CurrentWeatherResponse(
val coord: Coord,
@PrimaryKey
val id: Int,
val main: Main,
val name: String,
val sys: Sys,
val visibility: Int,
val weather: List<Weather>,
val wind: Wind
): Serializable

Đây là một Entity của Database tuy nhiên, Entity này có những property không phải dữ liệu nguyên thủy như: Coord, Main, Sys, List<Weather>, Wind. Sau đây chúng ta sẽ bắt tay vào định nghĩa lớp Converters để convert các propery này nhé:

class Converters {
  @TypeConverter
  fun toCoord(coord: String): Coord? {
      return Gson().fromJson<Coord>(coord,Coord::class.java)
  }

  @TypeConverter
  fun fromCoord(coord: Coord): String? {
      return Gson().toJson(coord)
  }

  @TypeConverter
  fun toWind(wind: String): Wind? {
      return Gson().fromJson<Wind>(wind,Wind::class.java)
  }

  @TypeConverter
  fun fromWind(wind: Wind): String? {
      return Gson().toJson(wind)
  }

  @TypeConverter
  fun toMain(main: String): Main? {
      return Gson().fromJson<Main>(main,Main::class.java)
  }

  @TypeConverter
  fun fromMain(main: Main): String? {
      return Gson().toJson(main)
  }

  @TypeConverter
  fun toSys(sys: String): Sys? {
      return Gson().fromJson<Sys>(sys,Sys::class.java)
  }

  @TypeConverter
  fun fromSys(sys: Sys): String? {
      return Gson().toJson(sys)
  }

  @TypeConverter
  fun toWeather(weather: String): List<Weather>? {
      val listType = object : TypeToken<ArrayList<Weather>>(){}.type
      return Gson().fromJson<List<Weather>>(weather,listType)
  }

  @TypeConverter
  fun fromWeather(weather: List<Weather>): String? {
      return Gson().toJson(weather)
  }
}

Như mình đã đề cập, Room chỉ lưu trữ các kiểu dữ liệu nguyên thủy nên giải pháp ở đây là convert Object -> dữ liệu nguyên thủy. Và mình sử dụng Gson để convert Object -> String. Bạn phải tạo 2 function để convert qua lại: Object -> String và String -> Object (như mình đã tạo là to... & from...) Đừng quên Anotation @TypeConverter trên mỗi function nhé.

3. Kết thúc

@Database(
    entities = [CurrentWeatherResponse::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class WeatherDatabase : RoomDatabase() {

    abstract fun getWeatherDao(): WeatherDao

    companion object{
        @Volatile
        private var instance: WeatherDatabase?=null
        private val LOCK = Any()
        operator fun invoke(context: Context) = instance?: synchronized(LOCK){
            instance?: createDatabase(context).also{
                instance = it
            }

        }
        private fun createDatabase(context: Context) =
            Room.databaseBuilder(
                context.applicationContext,
                WeatherDatabase::class.java,
                "weather.db"
            ).build()
    }
}

Bước cuối cùng là thêm Anotation @TypeConverters(Converters::class) ở abstract class Database nữa nhé. Vậy là bạn đã setup TypeConverter vào dự án của bạn thành công.

Code được lấy trong project:

Github: https://github.com/iamhiutrun/Weather_Forecast


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.