Escribe para buscar…

Custom Type

Persist non-primitive types in Room using TypeConverters or Embedded types.

Esta página todavía no se ha traducido — se muestra en su idioma original:English

Type Converter

Type converters are pairs of functions, annotated with @TypeConverter, that translate a single database column type to a Kotlin property type and back.

Typical uses:

  • Map an Instant to a Long for a SQLite integer column.
  • Map a Location to a String for a SQLite text column.
  • Map a collection of String to a single String (e.g., CSV) for a text column.
Note

Type converters are strictly 1:1 (one property ↔ one column).

Setting Up a Type Converter

  1. Create any Kotlin class to hold converter functions.
  2. For each type pair, create two functions: A→B and B→A. If input is null, return null. Ensure the round-trip preserves values.
  3. Annotate both functions with @TypeConverter.
  4. Bring them into scope with @TypeConverters on one of:
@TypeConverters on…Applies to…
RoomDatabaseeverything in the database
Entity classall properties in that entity
Entity propertythat property only
DAO classall DAO functions
DAO functionthat function (all params)
DAO function parameterthat single parameter

Example: an entity using converters for Instant, Location, and Set<String>:

kotlin
@Entity(tableName = "record")
@TypeConverters(InstantTypeConverter::class, LocationTypeConverter::class, SetTypeConverter::class)
data class Record(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    val instant: Instant = Clock.System.now(),
    val location: Location,
    val tags: Set<String> = setOf()
) {
    @Dao
    interface SQL {
        @Query("select * from record")
        suspend fun select(): List<Record>

        @Insert
        suspend fun insert(entity: Record)
    }
}

data class Location(val latitude: Double, val longitude: Double) {
    constructor(location: Location) : this(location.latitude, location.longitude)
}

InstantTypeConverter

SQLite does not have a native date/time type. The recommended approach is to store timestamps as the number of milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC).

Instant has a toEpochMilliseconds() function that returns this value.

kotlin
class InstantTypeConverter {
    @TypeConverter
    fun instantToLong(timestamp: Instant?) = timestamp?.toEpochMilliseconds()

    @TypeConverter
    fun longToInstant(timestamp: Long?) =
        timestamp?.let { Instant.fromEpochMilliseconds(it) }
}

With @TypeConverters(InstantTypeConverter::class) in scope, Room will persist Instant as a SQLite integer.

LocationTypeConverter

Persist a Location (latitude/longitude) as a single String in a text column (e.g., “latitude;longitude”):

A Location object contains a latitude, longitude, and perhaps other values (e.g., altitude). If we only care about the latitude and longitude, we could save those in the database in a single text column, so long as we can determine a good format to use for that string. One possibility is to have the two values separated by a semicolon.

The LocationTypeConverter class has a pair of functions designed to convert between a Location and a String:

kotlin
class LocationTypeConverter {

    @TypeConverter
    fun locationToString(location: Location?) =
        location?.let { "${it.latitude};${it.longitude}" }

    @TypeConverter
    fun stringToLocation(location: String?) = location?.let {
        val pieces = location.split(';')
        if (pieces.size == 2) {
            try {
                Location(pieces[0].toDouble(), pieces[1].toDouble())
            } catch (e: Exception) {
                null
            }
        } else {
            null
        }

    }
}

Estás leyendo una vista previa.

Inicia sesión para leer el artículo completo. Cualquier cuenta abre 4 artículos gratuitos al mes; el alumnado y el profesorado leen las páginas de su curso sin límite.

Iniciar sesión