Room 3.0

  
La biblioteca de persistencias de Room brinda una capa de abstracción para SQLite que permite acceder a la base de datos sin problemas y, al mismo tiempo, aprovechar toda la potencia de SQLite.
Actualización más reciente Versión estable Versión potencial Versión beta Versión alfa
11 de marzo de 2026 - - - 3.0.0-alpha01

Cómo declarar dependencias

Para agregar una dependencia en Room3, debes agregar el repositorio de Maven de Google a tu proyecto. Consulta el repositorio de Maven de Google para obtener más información.

Agrega las dependencias de los artefactos que necesites en el archivo build.gradle de tu app o módulo:

Kotlin

dependencies {
    val room_version = ""

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = ""

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

Para obtener información sobre el uso del complemento de KSP, consulta la documentación de inicio rápido de KSP.

Para obtener más información sobre las dependencias, consulta Cómo agregar dependencias de compilación.

Usa el complemento de Gradle de Room

Puedes usar el complemento de Gradle de Room para configurar opciones del compilador de Room. El complemento configura el proyecto de modo que los esquemas generados (que son un resultado de las tareas de compilación y se consumen para las migraciones automáticas) se configuren correctamente para tener compilaciones reproducibles y almacenables en caché.

Para agregar el complemento, define el complemento y su versión en el archivo de compilación de Gradle de nivel superior.

Groovy

plugins {
    id 'androidx.room3' version "$room_version" apply false
}

Kotlin

plugins {
    id("androidx.room3") version "$room_version" apply false
}

En el archivo de compilación de Gradle a nivel del módulo, aplica el complemento y usa la extensión room3.

Groovy

plugins {
    id 'androidx.room3'
}

room3 {
    schemaDirectory "$projectDir/schemas"
}

Kotlin

plugins {
    id("androidx.room3")
}

room3 {
    schemaDirectory("$projectDir/schemas")
}

Se requiere configurar un schemaDirectory cuando se usa el complemento de Gradle de Room. Esto configurará el compilador de Room y las diversas tareas de compilación y sus backends (kotlinc, KSP) para generar archivos de esquema en carpetas con variantes, por ejemplo, schemas/flavorOneDebug/com.package.MyDatabase/1.json. Estos archivos se deben confirmar en el repositorio para usarlos en la validación y las migraciones automáticas.

Comentarios

Tus comentarios ayudan a mejorar Jetpack. Avísanos si descubres nuevos errores o tienes ideas para mejorar esta biblioteca. Consulta los errores existentes de esta biblioteca antes de crear uno nuevo. Puedes agregar tu voto a un error existente haciendo clic en el botón de la estrella.

Crear un error nuevo

Consulta la documentación sobre la Herramienta de seguimiento de errores para obtener más información.

Versión 3.0

Versión 3.0.0-alpha01

11 de marzo de 2026

Lanzamiento de androidx.room3:room3-*:3.0.0-alpha01.

Room 3.0 (paquete androidx.room3) es una actualización de versión principal del paquete Room 2.x (androidx.room) que se enfoca en Kotlin Multiplatform (KMP).

Las APIs de anotación principales se mantienen igual junto con los componentes principales:

  • Una clase abstracta que extiende androidx.room3.RoomDatabase y se anota con @Database es el punto de entrada para el procesador de anotaciones de Room.
  • La declaración de la base de datos tiene una o más clases de datos que describen el esquema de la base de datos y están anotadas con @Entity.
  • Las operaciones de la base de datos se definen en declaraciones @Dao que contienen funciones de consulta cuyas instrucciones SQL se definen a través de la anotación @Query.
  • En el tiempo de ejecución, la implementación de la base de datos se puede obtener a través de un RoomDatabase.Builder que también se usa para configurar la base de datos.

La mayor parte de la documentación de la guía Cómo guardar contenido en una base de datos local con Room sigue siendo pertinente para Room 3.0.

A continuación, se mencionan los principales cambios incompatibles entre Room 2.x:

  • Nuevo paquete, androidx.room3.
  • Ya no se admiten las APIs de SupportSQLite, a menos que uses androidx.room3:room3-sqlite-wrapper.
  • Ahora todas las operaciones de la base de datos se basan en las APIs de Coroutine.
  • Solo se genera código Kotlin.
  • Se requiere el Procesamiento de Símbolos de Kotlin (KSP).

Junto con los cambios rotundos, Room 3.0 incorpora nuevas funcionalidades en comparación con la versión 2.x:

  • Compatibilidad con JS y WasmJS
  • Tipos de devolución de DAO personalizados

New Package

Para evitar problemas de compatibilidad con las implementaciones existentes de Room 2.x y para las bibliotecas con dependencias transitivas de Room (por ejemplo, WorkManager), Room 3.0 reside en un paquete nuevo, lo que significa que también tiene un nuevo ID de grupo y artefacto de Maven. Por ejemplo, androidx.room:room-runtime se convirtió en androidx.room3:room3-runtime, y las clases como androidx.room.RoomDatabase ahora se ubicarán en androidx.room3.RoomDatabase.

No hay APIs de SupportSQLite

Room 3.0 se basa por completo en las APIs de SQLiteDriver y ya no hace referencia a tipos de SupportSQLite, como SupportSQLiteDatabase, ni a tipos de Android, como Cursor. Este es el cambio más significativo entre Room 3.0 y 2.x, ya que se quitaron las APIs de RoomDatabase que reflejaban SupportSQLiteDatabase junto con la API para obtener un SupportSQLiteOpenHelper. Ahora se requiere un SQLiteDriver para compilar un RoomDatabase.

Por ejemplo, las APIs para operaciones directas de bases de datos se reemplazan por equivalentes de controladores:

// Room 2.x
roomDatabase.runInTransaction { ... }

// Room 3.x
roomDatabase.withWriteTransaction { ... }
// Room 2.x
roomDatabase.query("SELECT * FROM Song").use { cursor -> ... }

// Room 3.x
roomDatabase.useReaderConnection { connection ->
  connection.usePrepared("SELECT * FROM Song") { stmt -> ... }
}

Las APIs de devolución de llamada que tenían un SupportSQLiteDatabase como argumento también se reemplazaron por su API equivalente que tiene un SQLiteConnection como argumento. Estas son funciones de devolución de llamada de migraciones, como Migration.onMigrate() y AutoMigrationSpec.onPostMigrate(), junto con devoluciones de llamada de bases de datos, como RoomDatabase.Callback.onCreate(), RoomDatabase.Callback.onOpen(), etcétera.

Si se usaba Room en un proyecto de KMP, la migración a la versión 3.0 es más sencilla, ya que, en su mayoría, implica actualizar las referencias de importación. De lo contrario, se aplica la misma estrategia de migración de Room de KMP solo para Android a KMP. Consulta la Guía de migración de Room KMP.

Wrapper de SupportSQLite

Room 3.x conserva el wrapper de SupportSQLite creado en la versión 2.x para facilitar las migraciones y ahora se encuentra en un nuevo artefacto androidx.room3:room3-sqlite-wrapper. La API de compatibilidad te permite convertir un RoomDatabase en un SupportSQLiteDatabase. Las invocaciones de roomDatabase.openHelper.writableDatabase se pueden reemplazar por roomDatabase.getSupportWrapper().

Kotlin y corrutinas primero

Para mejorar la evolución de la biblioteca, Room 3.0 solo genera código Kotlin y solo es un procesador de símbolos de Kotlin (KSP). En comparación con Room 2.x, no hay generación de código Java y ya no es posible configurar el procesador de anotaciones a través de KAPT o JavaAP en Room 3.0. Ten en cuenta que KSP puede procesar fuentes de Java y que el compilador de Room generará código para bases de datos, entidades o DAO cuyas declaraciones de origen estén en Java. Se recomienda tener un proyecto con varios módulos en el que se concentre el uso de Room y se puedan aplicar el complemento de Gradle de Kotlin y KSP sin afectar el resto de la base de código.

Room 3.0 también requiere el uso de corrutinas y, más específicamente, las funciones DAO deben ser de suspensión, a menos que muestren un tipo reactivo, como un Flow o un tipo de datos que se muestra de DAO personalizado. Las APIs de Room para realizar operaciones de bases de datos también son funciones de suspensión, como RoomDatabase.useReaderConnection y RoomDatabase.useWriterConnection.

A diferencia de Room 2.x, ya no es posible configurar un RoomDatabase con un Executor. En cambio, se puede proporcionar un CoroutineContext junto con un dispatcher a través del compilador de la base de datos.

Las APIs de InvalidationTracker en Room 3.0 se basan en Flow, se quita InvalidationTracker.Observer junto con sus APIs relevantes addObserver y removeObserver. El mecanismo para reaccionar a las operaciones de la base de datos se realiza a través de flujos de corrutinas que se pueden crear a través de la API de createFlow() en InvalidationTracker.

Ejemplo de uso:

fun getArtistTours(from: Date, to: Date): Flow<Map<Artist, TourState>> {
    return db.invalidationTracker.createFlow("Artist").map { _ ->
        val artists = artistsDao.getAllArtists()
        val tours = tourService.fetchStates(artists.map { it.id })
        associateTours(artists, tours, from, to)
    }
}

Asistencia en la Web

La versión 3.0 de Room agrega JavaScript y WasmJs como destinos de KMP. En combinación con el lanzamiento de las interfaces SQLiteDriver (androidx.sqlite:sqlite) que también se orientan a JavaScript y WasmJs, y un nuevo controlador WebWorkerSQLiteDriver ubicado en el nuevo artefacto androidx.sqlite:sqlite-web, es posible usar Room en código común que se oriente a todas las plataformas principales de KMP.

Debido a la naturaleza asíncrona de las plataformas web, las APIs de Room que tomaban SQLiteStatement como argumento ahora son funciones de suspensión. Algunos ejemplos de estas funciones son Migration.onMigrate(), RoomDatabase.Callback.onCreate(), PooledConnection.usePrepared() y otras. En las APIs de controladores, las APIs asíncronas son comunes en todas las plataformas, y las síncronas son comunes para los objetivos que no son web. Por lo tanto, un proyecto que no se oriente a la Web puede seguir usando las APIs síncronas (SQLiteDriver.open(), SQLiteConnection.prepare() y SQLiteStatement.step()) en el código común. Mientras tanto, un proyecto que solo se orienta a la Web debe usar las APIs asíncronas (SQLiteDriver.openAsync(), SQLiteConnection.prepareAsync() y SQLiteStatement.stepAsync()).

Para mayor comodidad, el paquete androidx.sqlite también agregó funciones de extensión suspend con los nombres síncronos de las APIs mencionadas (con la adición de SQLiteConnection.executeSQL). Se recomiendan estas APIs cuando el proyecto se orienta a plataformas web y no web, ya que las APIs son declaraciones expect / actual que llamarán a la variante correcta según las plataformas. Estas son las APIs que usa el tiempo de ejecución de Room y que habilitan el uso del controlador en el código común para todas las plataformas compatibles.

Ejemplo de uso:

import androidx.sqlite.executeSQL
import androidx.sqlite.step

roomDatabase.useWriterConnection { connection ->
    val deletedSongs = connection.usePrepared(
        "SELECT count(*) FROM Song"
    ) { stmt ->
        stmt.step()
        stmt.getLong(0)
    }
    connection.executeSQL("DELETE FROM Song")
    deletedSongs
}

WebWorkerSQLiteDriver es una implementación de SQLiteDriver que se comunica con un Web Worker para realizar operaciones de bases de datos fuera del subproceso principal y permite almacenar la base de datos en el Origin Private File System (OPFS). Para crear una instancia del controlador, se requiere un trabajador que implemente un protocolo de comunicación simple. El protocolo se describe en el KDoc de WebWorkerSQLiteDriver.

Actualmente, WebWorkerSQLiteDriver no se incluye con un worker predeterminado que implemente el protocolo de comunicación, pero, a modo de ejemplo, la base de código de androidx contiene una implementación de worker que se puede usar en tu proyecto. Utiliza WASM de SQLite y almacena la base de datos en OPFS. El worker de ejemplo se publica como un paquete NPM local y, gracias a la compatibilidad de Kotlin con las dependencias de NPM, se puede crear un pequeño módulo de KMP para entregar el worker.

Consulta el siguiente proyecto de GitHub que demuestra el uso de un Web Worker local para Room.

Una vez que se configura un trabajador en el proyecto, la configuración de Room para la Web es similar a la de otras plataformas:

fun createDatabase(): MusicDatabase {
    return Room.databaseBuilder<MusicDatabase>("music.db")
        .setDriver(WebWorkerSQLiteDriver(createWorker()))
        .build()
}

fun createWorker() =
    Worker(js("""new URL("sqlite-web-worker/worker.js", import.meta.url)"""))

Una versión futura del controlador web podría contener un trabajador predeterminado publicado en NPM, lo que simplificaría la configuración web.

Tipos de datos que se muestran del DAO personalizado

Varias integraciones de tipos de datos devueltos por DAO, como las de RxJava y Paging, se transformaron para usar una nueva API en Room 3.0 llamada convertidores de tipos de datos devueltos por DAO. Una función de conversión del tipo de datos que se muestra del DAO (@DaoReturnTypeConverter) permite transformar el resultado de una función del DAO en un tipo personalizado definido por la función anotada. Estas funciones permiten participar en el código generado de Room que transforma los resultados de las consultas en objetos de datos. Las clases que contienen conversores de tipos de datos devueltos por el DAO deben registrarse a través de las anotaciones @DaoReturnTypeConverters en las declaraciones @Database o @Dao.

Por ejemplo, para que una consulta de DAO devuelva un PagingSource, ahora se debe registrar la clase de convertidor ubicada en androidx.room3:room3-paging:

@Dao
@DaoReturnTypeConverters(PagingSourceDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song)
    fun getSongsPaginated(): PagingSource<Int, Song>
}

Las integraciones existentes se movieron a los convertidores de tipo de datos que se muestran del DAO:

Tipo de devolución Clase del convertidor Artefacto
PagingSource PagingSourceDaoReturnTypeConverter androidx.room3:room3-paging
Observable, Flowable, Completable, Single, Maybe RxDaoReturnTypeConverters androidx.room3:room3-rxjava3
ListenableFuture GuavaDaoReturnTypeConverter androidx.room3:room3-guava
LiveData LiveDataDaoReturnTypeConverter androidx.room3:room3-livedata

Al igual que los conversores de tipo de columna, los conversores de tipo de devolución de DAO pueden definirse en la aplicación. Por ejemplo, una aplicación podría declarar un @DaoReturnTypeConverter para el tipo web kotlin.js.Promise.

object PromiseDaoReturnTypeConverter {
    @DaoReturnTypeConverter([OperationType.READ, OperationType.WRITE])
    fun <T> convert(
        db: RoomDatabase,
        executeAndConvert: suspend () -> T
    ): Promise<T> {
        return db.getCoroutineScope().promise { executeAndConvert() }
    }
}

El convertidor anterior permite que las funciones de consulta de DAO muestren Promise:

@Dao
@DaoReturnTypeConverters(PromiseDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song")
    fun getAllSongs(): Promise<List<Song>>
}

Una función @DaoReturnTypeConverter tiene algunos requisitos en cuanto a la cantidad de parámetros que debe tener y sus tipos. Los parámetros posibles son los siguientes:

  • db: RoomDatabase: (Opcional) Proporciona acceso a la instancia de RoomDatabase, que puede ser útil para realizar operaciones de bases de datos adicionales o acceder al alcance de la corrutina.
  • tableNames: Array<String>: (Opcional) Contiene las tablas a las que se accedió en la consulta, lo que resulta útil para admitir tipos observables o reactivos cuando se combina con la API de InvalidationTracker.createFlow() de Room.
  • rawQuery: RoomRawQuery: (Opcional) Contiene en el tiempo de ejecución una instancia de la consulta, lo que permite transformaciones como la estrategia LIMIT / OFFSET implementada por PagingSourceDaoReturnTypeConverter.
  • executeAndConvert: suspend () -> T: (Obligatorio) Es la función generada por Room que ejecutará la consulta y analizará su resultado en objetos de datos.

Para obtener más información sobre los requisitos para crear un convertidor de tipos de devolución de DAO, consulta el KDoc en la API de @DaoReturnTypeConverter.