Save data in a local database using Room
Apps that handle non-trivial amounts of structured data can benefit greatly from persisting that data locally. The most common use case is to cache relevant pieces of data so that when the device cannot access the network, the user can still browse that content while they are offline.
The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. In particular, Room provides the following benefits:
- Compile-time verification of SQL queries.
- Convenience annotations that minimize repetitive and error-prone boilerplate code.
- Streamlined database migration paths.
There are three major components in Room:
- The database class that holds the database and serves as the main access point for the underlying connection to your app’s persisted data.
- Data entities that represent tables in your app’s database.
- Data access objects (DAOs) that provide methods that your app can use to query, update, insert, and delete data in the database.
@Entity
public class User {
@PrimaryKey
public int uid;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
}
@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);
}
The database class must satisfy the following conditions:
-
The class must be annotated with a @Database annotation that includes an entities array that lists all of the data entities associated with the database.
-
The class must be an abstract class that extends RoomDatabase. For each DAO class that is associated with the database, the database class must define an abstract method that has zero arguments and returns an instance of the DAO class.
You define each Room entity as a class that is annotated with @Entity. A Room entity includes fields for each column in the corresponding table in the database, including one or more columns that comprise the primary key.
@Entity
public class User {
@PrimaryKey
public int id;
public String firstName;
public String lastName;
}
@Entity(tableName = "users")
public class User {
@PrimaryKey
public int id;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
}
Provide table search support
Room supports several types of annotations that make it easier for you to search for details in your database’s tables. Use full-text search unless your app’s minSdkVersion is less than 16.
Anatomy of a DAO
You can define each DAO as either an interface or an abstract class. For basic use cases, you should usually use an interface. In either case, you must always annotate your DAOs with @Dao. DAOs don’t have properties, but they do define one or more methods for interacting with the data in your app’s database.
@Dao
public interface UserDao {
@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List<User> getAll();
}
Insert
@Dao
public interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List<User> friends);
}
Delete
@Dao
public interface UserDao {
@Delete
public void deleteUsers(User... users);
}