Cómo migrar de SQLite a Room

La biblioteca de persistencias de Room brinda varios beneficios en comparación con el uso directo de las APIs de SQLite como los siguientes:

  • Verificación del tiempo de compilación de las consultas en SQL
  • Anotaciones de conveniencia que minimizan el código estándar repetitivo y propenso a errores
  • Rutas de migración de bases de datos optimizadas

Si tu app tiene una implementación de SQLite que no es Room, lee esta página para obtener información sobre cómo migrar a Room. Si Room es la primera implementación de SQLite en tu app, consulta Cómo guardar contenido en una base de datos local con Room para obtener información básica de uso.

Pasos de la migración

Sigue estos pasos para migrar tu implementación de SQLite a Room. Si tu implementación de SQLite usa una base de datos de gran tamaño o búsquedas complejas, quizás te convenga migrar a Room de manera gradual. Para obtener más información sobre una estrategia de migración incremental, consulta Migración incremental.

Actualiza las dependencias

Para usar Room en tu app, debes incluir las dependencias apropiadas en el archivo build.gradle de la app. Para obtener más información sobre las dependencias de Room, consulta Configuración.

Actualiza las clases de modelo en entidades de datos

Room usa entidades de datos para representar las tablas en la base de datos. Cada clase de entidad representa una tabla y tiene propiedades que representan columnas en esa tabla. Sigue estos pasos para actualizar las clases de modelo existentes para que sean entidades de Room:

  1. Agrega la anotación @Entity a la declaración de clase para indicar que se trata de una entidad de Room. De manera opcional, puedes usar la propiedad tableName para indicar que la tabla resultante debe tener un nombre diferente al nombre de la clase.
  2. Anota la propiedad de clave primaria con @PrimaryKey.
  3. Si alguna de las columnas de la tabla resultante debe tener un nombre que sea diferente al nombre de la propiedad correspondiente, agrega la anotación al campo con @ColumnInfo y establece la propiedad name con el nombre de columna correcto.
  4. Si la clase tiene propiedades que no deseas conservar en la base de datos, agrega la anotación @Ignore a esas propiedades para indicar que Room no debe crear columnas para ellas en la tabla correspondiente.
  5. Si la clase tiene más de un constructor, indica qué constructor Room debe usar al agregar la anotación @Ignore al resto de los constructores.

@Entity(tableName = "users")
data class User(
    @PrimaryKey @ColumnInfo(name = "userid") val id: String,
    @ColumnInfo(name = "username") val userName: String?,
    @ColumnInfo(name = "last_update") val date: Date?,
)

Crea DAOs

Room usa objetos de acceso a datos (DAO) para definir funciones que acceden a la base de datos. Sigue las instrucciones del artículo para acceder a los datos con DAO de Room para reemplazar tus funciones de consulta existentes por DAOs.

Crea una clase de base de datos

Las implementaciones de Room usan una clase de base de datos para administrar una instancia de la base de datos. Tu clase de base de datos debe extender RoomDatabase y hacer referencia a todas las entidades y DAOs que definiste.

@Database(entities = [User::class], version = 2)
@ColumnTypeConverters(DateConverter::class)
abstract class UsersDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Define una ruta de migración

Debido a que el número de versión de la base de datos está cambiando, debes definir un Migration objeto para conservar los datos existentes de la base de datos. Si el esquema de la base de datos no cambia, esta migración puede estar vacía.

val MIGRATION_1_2 = object : Migration(1, 2) {
    override suspend fun migrate(connection: SQLiteConnection) {
        // Empty implementation, because the schema isn't changing.
    }
}

Para obtener más información sobre las rutas de migración de bases de datos en Room, consulta Cómo migrar tu base de datos.

Actualiza la creación de instancias de la base de datos

Después de definir una clase de base de datos y una ruta de migración, puedes usar Room.databaseBuilder para crear una instancia de la base de datos con la ruta de migración aplicada:

val db =
    Room.databaseBuilder<UsersDatabase>(applicationContext, "database-name")
        .addMigrations(MIGRATION_1_2)
        .build()

Prueba tu implementación

Asegúrate de probar tu nueva implementación de Room:

Migración incremental

Si tu app usa una base de datos grande y compleja, quizás no sea posible migrarla a Room de una sola vez. En cambio, puedes implementar las entidades de datos y la base de datos de Room como primer paso y, luego, migrar tus funciones de consulta a DAO.

Para implementar una migración incremental, obtén un wrapper de compatibilidad SupportSQLiteDatabase con la función de extensión roomDatabase.getSupportWrapper del artefacto androidx.room3:room3-sqlite-wrapper. Este wrapper te permite ejecutar consultas SQL directas de estilo Android en la base de datos administrada por Room con las APIs de SQLite de Android:

// Get SupportSQLiteDatabase wrapper
val legacyDb = roomDatabase.getSupportWrapper()
legacyDb.execSQL("INSERT INTO users ...")