androidx.room
Room is a Database Object Mapping library that makes it easy to access database on Android applications.
Rather than hiding the details of SQLite, Room tries to embrace them by providing convenient APIs to query the database and also verify such queries at compile time. This allows you to access the full power of SQLite while having the type safety provided by Java SQL query builders.
There are 3 major components in Room.
Database
: This annotation marks a class as a database. It should be an abstract class that extendsRoomDatabase
. At runtime, you can acquire an instance of it viaRoom.databaseBuilder
orRoom.inMemoryDatabaseBuilder
.The database class defines the list of entities and data access objects in the database. It is also the main access point for the underlying connection.
Entity
: This annotation marks a class as a database row. For eachEntity
, a database table is created to hold the items. The Entity class must be referenced in theDatabase#entities
array. Each field of the Entity (and its super class) is persisted in the database unless it is denoted otherwise (seeEntity
docs for details).Dao
: This annotation marks a class or interface as a Data Access Object. Data access objects are the main components of Room that are responsible for defining the methods that access the database. The class that is annotated withDatabase
must have an abstract method that has 0 arguments and returns the class that is annotated with Dao. While generating the code at compile time, Room will generate an implementation of this class.Using Dao classes for database access rather than query builders or direct queries allows you to keep a separation between different components and easily mock the database access while testing your application.
// File: Song.java @Entity public class Song { @PrimaryKey private int id; private String name; @ColumnInfo(name = "release_year") private int releaseYear; // getters and setters are ignored for brevity but they are required for Room to work. } // File: SongDao.java @Dao public interface SongDao { @Query("SELECT * FROM song") List<Song> loadAll(); @Query("SELECT * FROM song WHERE id IN (:songIds)") List<Song> loadAllBySongId(int... songIds); @Query("SELECT * FROM song WHERE name LIKE :name AND release_year = :year LIMIT 1") Song loadOneByNameAndReleaseYear(String first, int year); @Insert void insertAll(Song... songs); @Delete void delete(Song song); } // File: MusicDatabase.java @Database(entities = {Song.class}) public abstract class MusicDatabase extends RoomDatabase { public abstract SongDao songDao(); }You can create an instance of
MusicDatabase
as follows:
MusicDatabase db = Room .databaseBuilder(getApplicationContext(), MusicDatabase.class, "database-name") .build();Since Room verifies your queries at compile time, it also detects information about which tables are accessed by the query or what columns are present in the response.
You can observe a particular table for changes using the InvalidationTracker
class which you can acquire via RoomDatabase.getInvalidationTracker
.
For convenience, Room allows you to return LiveData
from Query
methods. It will automatically observe the related tables as long as the LiveData
has active observers.
// This live data will automatically dispatch changes as the database changes. @Query("SELECT * FROM song ORDER BY name LIMIT 5") LiveData<Song> loadFirstFiveSongs();
You can also return arbitrary data objects from your query results as long as the fields in the object match the list of columns in the query response. This makes it very easy to write applications that drive the UI from persistent storage.
class IdAndSongHeader { int id; @ColumnInfo(name = "header") String header; } // DAO @Query("SELECT id, name || '-' || release_year AS header FROM song") public IdAndSongHeader[] loadSongHeaders();If there is a mismatch between the query result and the POJO, Room will print a warning during compilation.
Please see the documentation of individual classes for details.
Interfaces
RoomDatabase.QueryCallback |
Callback interface for when SQLite queries are executed. |
Classes
DatabaseConfiguration |
Configuration class for a |
InvalidationTracker |
InvalidationTracker keeps a list of tables modified by queries and notifies its callbacks about these tables. |
InvalidationTracker.Observer |
An observer that can listen for changes in the database. |
MultiInstanceInvalidationService |
A |
RoomDatabase |
Base class for all Room databases. |
RoomDatabase.Builder |
Builder for RoomDatabase. |
RoomDatabase.Callback |
Callback for |
RoomDatabase.MigrationContainer |
A container to hold migrations. |
RoomDatabase.PrepackagedDatabaseCallback |
Callback for |
RoomWarnings |
The list of warnings that are produced by Room. |
RxRoom |
Helper class to add RxJava2 support to Room. |
Exceptions
EmptyResultSetException |
Thrown by Room when the query in a Single |
Objects
FtsOptions |
|
Room |
Utility functions for Room. |
Annotations
AutoMigration |
Declares an automatic migration on a Database. |
BuiltInTypeConverters |
Flags to turn on/off extra type converters provided by Room. |
ColumnInfo |
Allows specific customization about the column associated with this field. |
ColumnInfo.Collate |
|
ColumnInfo.SQLiteTypeAffinity |
The SQLite column type constants that can be used in typeAffinity() |
Dao |
Marks the class as a Data Access Object. |
Database |
Marks a class as a RoomDatabase. |
DatabaseView |
Marks a class as an SQLite view. |
Delete |
Marks a method in a |
DeleteColumn |
Repeatable annotation declaring the deleted columns in the |
DeleteColumn.Entries |
Container annotation for the repeatable annotation |
DeleteTable |
Repeatable annotation declaring the deleted tables in the |
DeleteTable.Entries |
Container annotation for the repeatable annotation |
Embedded |
Marks a field of an |
Entity |
Marks a class as an entity. |
ExperimentalRoomApi |
APIs marked with ExperimentalRoomApi are experimental and may change. |
ForeignKey |
Declares a foreign key on another |
ForeignKey.Action |
Constants definition for values that can be used in |
Fts3 |
Marks an |
Fts4 |
Marks an |
Ignore |
Ignores the marked element from Room's processing logic. |
Index |
Declares an index on an |
Insert |
Marks a method in a |
Junction |
Declares a junction to be used for joining a relationship. |
MapColumn |
Declares which column is used to build a map or multimap return value in a |
MapInfo |
This annotation is deprecated. Use @MapColumn instead. |
OnConflictStrategy |
Set of conflict handling strategies for various {@link Dao} methods. |
PrimaryKey |
Marks a field in an |
ProvidedAutoMigrationSpec |
Marks a class as an auto migration spec that will be provided to Room at runtime. |
ProvidedTypeConverter |
Marks a class as a type converter that will be provided to Room at runtime. |
Query |
Marks a method in a |
RawQuery |
Marks a method in a |
Relation |
A convenience annotation which can be used in a POJO to automatically fetch relation entities. |
RenameColumn |
Repeatable annotation declaring the renamed columns in the |
RenameColumn.Entries |
Container annotation for the repeatable annotation |
RenameTable |
Repeatable annotation declaring the renamed tables in the new version of an auto migration. |
RenameTable.Entries |
Container annotation for the repeatable annotation |
RewriteQueriesToDropUnusedColumns |
When present, |
SkipQueryVerification |
Skips database verification for the annotated element. |
Transaction |
Marks a method in a |
TypeConverter |
Marks a method as a type converter. |
TypeConverters |
Specifies additional type converters that Room can use. |
Update |
Marks a method in a |
Upsert |
Marks a method in a |
Enums
BuiltInTypeConverters.State |
Control flags for built in converters. |
FtsOptions.MatchInfo |
|
FtsOptions.Order |
|
Index.Order |
|
RoomDatabase.JournalMode |
Journal modes for SQLite database. |
Extension functions summary
Flow<Set<String>> |
RoomDatabase.invalidationTrackerFlow( Creates a |
suspend R |
<R : Any?> RoomDatabase.withTransaction(block: suspend () -> R) Calls the specified suspending |
Extension functions
invalidationTrackerFlow
fun RoomDatabase.invalidationTrackerFlow(
vararg tables: String,
emitInitialState: Boolean = true
): Flow<Set<String>>
Creates a Flow
that listens for changes in the database via the InvalidationTracker
and emits sets of the tables that were invalidated.
The Flow will emit at least one value, a set of all the tables registered for observation to kick-start the stream unless emitInitialState
is set to false
.
If one of the tables to observe does not exist in the database, this Flow throws an IllegalArgumentException
during collection.
The returned Flow can be used to create a stream that reacts to changes in the database:
fun getArtistTours(from: Date, to: Date): Flow<Map<Artist, TourState>> {
return db.invalidationTrackerFlow("Artist").map { _ ->
val artists = artistsDao.getAllArtists()
val tours = tourService.fetchStates(artists.map { it.id })
associateTours(artists, tours, from, to)
}
}
withTransaction
suspend fun <R : Any?> RoomDatabase.withTransaction(block: suspend () -> R): R
Calls the specified suspending block
in a database transaction. The transaction will be marked as successful unless an exception is thrown in the suspending block
or the coroutine is cancelled.
Room will only perform at most one transaction at a time, additional transactions are queued and executed on a first come, first serve order.
Performing blocking database operations is not permitted in a coroutine scope other than the one received by the suspending block. It is recommended that all Dao
function invoked within the block
be suspending functions.
The internal dispatcher used to execute the given block
will block an utilize a thread from Room's transaction executor until the block
is complete.