Room 包含 3 个主要组件:
数据库:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。
使用 @Database 注释的类应满足以下条件:
在运行时,可以通过调用 Room.databaseBuilder()或Room.inMemoryDatabaseBuilder() 获取 Database 的实例。
Entity:表示数据库中的表。
DAO:包含用于访问数据库的方法。
应用使用 Room 数据库来获取与该数据库关联的数据访问对象 (DAO)。然后,应用使用每个 DAO 从数据库中获取实体,然后再将对这些实体的所有更改保存回数据库中。最后,应用使用实体来获取和设置与数据库中的表列相对应的值。
使用 Room 持久性库时,可以将相关字段集定义为实体。对于每个实体,系统会在关联的 Database 对象中创建一个表来存储这些项。必须通过 Database 类中的 entities 数组引用实体类。
- [ ] 注意:要在应用中使用实体,请向应用的 build.gradle 文件中添加架构组件工件。
在应用或模块的 build.gradle 文件中添加所需工件的依赖项:
dependencies {
def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$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"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
JAVA代码
@Entity
public class User {
@PrimaryKey
public int id;
public String firstName;
public String lastName;
}
2.创建视图
@DatabaseView("SELECT user.id, user.name, user.departmentId," +
"department.name AS departmentName FROM user " +
"INNER JOIN department ON user.departmentId = department.id")
public class UserDetail {
public long id;
public String name;
public long departmentId;
public String departmentName;
}
要使用 Room 持久性库访问应用的数据,您需要使用数据访问对象 (DAO)。这些 Dao 对象构成了 Room 的主要组件,因为每个 DAO 都包含一些方法,这些方法提供对应用数据库的抽象访问权限。
通过使用 DAO 类(而不是查询构建器或直接查询)访问数据库,您可以拆分数据库架构的不同组件。此外,借助 DAO,您可以在测试应用时轻松模拟数据库访问。
注意:在将 DAO 类添加到您的应用之前,请先向应用的 build.gradle 文件中添加架构组件工件。
DAO 既可以是接口,也可以是抽象类。如果是抽象类,则该 DAO 可以选择有一个以 RoomDatabase 为唯一参数的构造函数。Room 会在编译时创建每个 DAO 实现。
1.Insert
@Dao
public interface MyDao {
@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);
}
2.Update
@Dao
public interface MyDao {
@Update
public void updateUsers(User... users);
}
3.Delete
@Dao
public interface MyDao {
@Delete
public void deleteUsers(User... users);
}
4.查询
@Dao
public interface MyDao {
@Query("SELECT * FROM user")
public User[] loadAllUsers();
}
1.在 Android 设备上测试
要测试数据库实现,推荐的方法是编写在 Android 设备上运行的 JUnit 测试。由于执行这些测试不需要创建 Activity,因此它们的执行速度应该比界面测试速度快。
在设置测试时,您应创建内存版本的数据库以使测试更加封闭,如以下示例所示:
@RunWith(AndroidJUnit4.class)
public class SimpleEntityReadWriteTest {
private UserDao userDao;
private TestDatabase db;
@Before
public void createDb() {
Context context = ApplicationProvider.getApplicationContext();
db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
userDao = db.getUserDao();
}
@After
public void closeDb() throws IOException {
db.close();
}
@Test
public void writeUserAndReadInList() throws Exception {
User user = TestUtil.createUser(3);
user.setName("george");
userDao.insert(user);
List<User> byName = userDao.findUsersByName("george");
assertThat(byName.get(0), equalTo(user));
}
}
2.在主机上测试数据库
Room 使用 SQLite 支持库,该支持库提供了与 Android 框架类中的接口相对应的接口。通过此项支持,您可以传递该支持库的自定义实现来测试数据库查询。