本文翻译自官网
使用Room进行持久化存储---综述
通过 Room entities 定义数据 ---Room 系列(1)
使用 Room 的 DAO 访问数据---Room 系列(2)
Android 中使用 Room 实践
Room 提供了一个建立在 SQLite 之上的抽象层,使得我们能够更流畅的进行数据库访问。
对于处理大量结构化数据的应用来说,将数据持久化存储到本地处理是一种较好的方式。 通常,我们会缓存相关的数据,当用户没有网络的时候,可以进行离线浏览,当设备在线之后,在同步数据。
而 Room 实际上就专注于这种方式。我们强烈推荐你使用 Room 替代 SQLite。当然,如果你更喜欢使用 SQLite API,Android仍然支持直接使用 SQLite 进行数据库访问。
在 Room 中,有三个主要概念:
-
Database:数据库的实际持有者,底层连接的主要访问点。以 @Database 进行注解的类,应该满足以下几个条件:1. 这是一个抽象类,继承自 RoomDatabase;2. 包含一系列与该数据库相关的 entity ;3. 至少有一个方法返回以 @Dao 进行注解的对象,同时,该方法没有参数。
在运行的时候,可以通过调用 Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder() 方法请求一个 Database 实例。
// User and Book are classes annotated with @Entity.
@Database(version = 1, entities = {User.class, Book.class})
abstract class AppDatabase extends RoomDatabase() {
// BookDao is a class annotated with @Dao.
abstract public BookDao bookDao();
// UserDao is a class annotated with @Dao.
abstract public UserDao userDao();
// UserBookDao is a class annotated with @Dao.
abstract public UserBookDao userBookDao();
}
- Entity:代表了 database 中的一张 table 。
-
DAO:包含有访问数据库的方法。
User.java
@Entity
public class User {
@PrimaryKey
private int uid;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
// Getters and setters are ignored for brevity,
// but they're required for Room to work.
}
UserDao.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.java
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
创建了上述的文件之后,通过下面代码获取一个数据库实例:
AppDatabase db = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, "database-name").build();
注意,通常,我们应该以单例模式实例化 AppDatabase 对象,因为每个 RoomDatabase 实例花销比较大,而我们往往不需要这么多的实例化对象。