Room proporciona una capa de abstracción sobre SQLite que permite acceder a la base de datos sin problemas y, al mismo tiempo, aprovechar toda la potencia de SQLite.
Las apps que controlan grandes cantidades de datos estructurados pueden beneficiarse con la posibilidad de conservar esos datos localmente. El caso práctico más común es almacenar en caché datos relevantes. De esa manera, cuando el dispositivo no puede acceder a la red, el usuario de todos modos puede explorar ese contenido mientras está desconectado. Cualquier cambio de contenido iniciado por el usuario se sincroniza con el servidor una vez que el dispositivo vuelve a estar en línea.
Como Room se ocupa de estas inquietudes por ti, te recomendamos utilizar Room en lugar de SQLite. Sin embargo, si prefieres usar las API de SQLite directamente, lee Cómo guardar datos mediante SQLite.
Para usar Room en tu app, agrega las siguientes dependencias al archivo build.gradle
de tu app:
Kotlin
dependencies { def room_version = "2.2.6" implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" // optional - Kotlin Extensions and Coroutines support for Room implementation "androidx.room:room-ktx:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" }
Java
dependencies { def room_version = "2.2.6" implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" // optional - RxJava support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" }
Estos son los 3 componentes principales de Room:
Base de datos: Contiene el titular de la base de datos y sirve como punto de acceso principal para la conexión subyacente a los datos persistentes y relacionales de tu app.
La clase anotada con
@Database
debe cumplir con las siguientes condiciones:- Ser una clase abstracta que extiende
RoomDatabase
- Incluir la lista de entidades asociadas con la base de datos dentro de la anotación
- Contener un método abstracto que tenga 0 argumentos y muestre la clase anotada con
@Dao
En el entorno de ejecución, puedes adquirir una instancia de
Database
llamando aRoom.databaseBuilder()
oRoom.inMemoryDatabaseBuilder()
.- Ser una clase abstracta que extiende
Entidad: Representa una tabla dentro de la base de datos.
DAO: Contiene los métodos utilizados para acceder a la base de datos.
La app usa la base de datos de Room para obtener los objetos de acceso a los datos (DAO) asociados con esa base de datos. Luego, la app usa cada DAO para obtener entidades de la base de datos y guardar los cambios realizados en esas entidades en la base de datos. Por último, la app usa una entidad para obtener y configurar valores que corresponden a columnas de tabla dentro de la base de datos.
Esta relación entre los diferentes componentes de Room aparece en la Figura 1:

En el siguiente fragmento de código, se muestra una configuración de base de datos de ejemplo con una entidad y un DAO:
User
Kotlin
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Java
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
UserDao
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List<User> @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
AppDatabase
Kotlin
@Database(entities = arrayOf(User::class), version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
Java
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
Después de crear los archivos anteriores, obtendrás una instancia de la base de datos creada con el siguiente código:
Kotlin
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
Java
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
Nota: Si tu app se ejecuta en un solo proceso, debes seguir el patrón de diseño singleton cuando crees una instancia de un objeto AppDatabase
. Cada instancia RoomDatabase
es bastante costosa y rara vez necesitas acceder a varias instancias en un mismo proceso.
Si tu app se ejecuta en varios procesos, incluye enableMultiInstanceInvalidation()
en tu invocación del creador de bases de datos. De esa manera, cuando tienes una instancia de AppDatabase
en cada proceso, puedes invalidar el archivo de base de datos compartido en un proceso y esta invalidación se propaga automáticamente a las instancias de AppDatabase
dentro de otros procesos.
Para realizar una experiencia práctica con Room, prueba los codelabs Room de Android con un objeto View y Persistencias de Android. Si deseas explorar los ejemplos de código de Room, consulta los ejemplos de los componentes de la arquitectura de Android.