目录
- 一、简介
- 1.1 主要组件
- 1.2 三者关系
- 二、基础使用
- 2.1 依赖导入
- 2.2 Student 实体类定义
- 2.3 StudentDao 操作接口类
- 2.4 StudentDataBase 类
- 2.5 RoomTestActivity 类
- 三、参考链接
一、简介
JetPack 中的 Room 是一个用于在 SQLite 数据库上提供抽象层的持久性库。它允许开发者在应用中使用更加简洁和流畅的方式来操作数据库,同时提供了一些强大的功能,如编译时的 SQL 检查、类型安全的查询以及 LiveData 和 RxJava 的支持。
Room 的一些重要特性和组件:
- 1.
Entity
:Entity 是一个在数据库中代表表的类。每个 Entity 包含一组字段,这些字段对应于表中的列。通过在 Entity 类中定义字段和注解,开发者可以轻松地映射数据库表的结构。- 2.
DAO
(Data Access Object):DAO 是一个包含用于访问数据库的方法的接口或抽象类。开发者可以在 DAO 中定义各种数据库操作,如插入、更新、删除和查询数据的方法。Room 在编译时会生成实现 DAO 的具体类。- 3.
Database
:Database 是一个抽象类,通过注解 @Database 来标记。它是 Room 数据库的主要入口点,用于获取 DAO 实例并管理数据库连接。开发者需要创建一个继承自 RoomDatabase 的子类,并在其中定义数据库的版本号、实体类和 DAO 接口。- 4.
TypeConverters
:TypeConverters 允许开发者自定义将非标准数据类型(如 Date、List 等)转换为 Room 可以存储的数据类型。通过编写自定义的 TypeConverter 类并将其应用于数据库字段,可以实现数据类型的转换和存储。- 5.
LiveData 和 RxJava 支持
:Room 提供了对 LiveData 和 RxJava 的支持,使开发者能够在数据库发生变化时收到通知并更新界面。通过将查询返回的数据类型设置为 LiveData 或 Flowable,可以轻松实现响应式的数据更新。- 6.
Database Migrations
:Room 支持数据库迁移,允许开发者在数据库结构发生变化时保留现有数据。通过编写 Migration 类并将其应用于数据库构建器,可以在数据库版本升级时执行必要的迁移操作。
Room是SQLite数据库的抽象
1.1 主要组件
Room 包含三个主要组件:
Entity
:实体类,对应的是数据库的一张表结构,使用注解@Entity标记
Dao
:包含访问一系列访问数据库的方法,使用注解@Dao标记
DataBase
:数据库持有者,作为与应用持久化相关数据的底层连接的主要接入点。使用注解@Database标记,另外需要满足以下条件:定义的类必须继承于RoomDatabase的抽象类,在注解中需要定义与数据库相关联的实体类列表。包含一个没有参数的抽象方法并且返回一个Dao对象。
1.2 三者关系
Entity 类表示数据库中的表结构。
Dao 接口定义与数据库的交互操作。
Database 类表示整个数据库,包含了一组 Entity,并提供了获取 Dao 实例的方法。
通过这种组织结构,可以轻松地定义数据库表结构、操作方法,并将它们组织在一起,以便 Room 可以管理数据库的创建、升级和访问。
二、基础使用
通过一个简单示例,演示Room如何生成数据库文件以及实现数据库的增删改查等操作。
2.1 依赖导入
implementation "androidx.room:room-runtime:2.2.0"
annotationProcessor "androidx.room:room-compiler:2.2.0" // For Java
// 如果需要在调试时查看 Room 数据库的内容
debugImplementation "androidx.room:room-testing:2.2.0"
2.2 Student 实体类定义
@Entity
public class Student {
//主键SQL 唯一的autoGenerate自增长
@PrimaryKey(autoGenerate = true)
private int uid;
@ColumnInfo(name = "name")
private String name;
@ColumnInfo(name = "pwd")
private String pwd;
@ColumnInfo(name = "address")
private int address;
public Student(String name, String pwd, int address) {
this.name = name;
this.pwd = pwd;
this.address = address;
}
public void setUid(int uid) {
this.uid = uid;
}
public void setName(String name) {
this.name = name;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public void setAddress(int address) {
this.address = address;
}
public int getUid() {
return uid;
}
public String getName() {
return name;
}
public String getPwd() {
return pwd;
}
public int getAddress() {
return address;
}
@Override
public String toString() {
return "Student{" +
"uid=" + uid +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
", address='" + address + '\'' +
'}';
}
}
2.3 StudentDao 操作接口类
@Dao
public interface StudentDao {
@Insert
void insert(Student... student);
@Delete
void delete(Student student);
@Update
void update(Student student);
@Query("select * from Student")
List<Student> getall();
//查询一条
@Query("select * from Student where name like:name")
Student findByName(String name);
//查询数组多个记录
@Query("select * from Student where uid in(:userIds)")
List<Student> getallId(int[] userIds);
}
2.4 StudentDataBase 类
//exportSchema 导出模式
@Database(entities = {Student.class}, version = 1, exportSchema = false)
public abstract class StudentDataBase extends RoomDatabase {
//暴露DAO
public abstract StudentDao userDao();
}
2.5 RoomTestActivity 类
public class RoomTestActivity extends AppCompatActivity {
ActivityViewmodelBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityViewmodelBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//数据库的操作应该是在子线程
DbTest t = new DbTest();
t.start();
}
//测试刚刚写的三个角色Room数据库 增删改查
class DbTest extends Thread {
@Override
public void run() {
super.run();
//数据库的操作都在这里
StudentDataBase henryDB = Room.databaseBuilder
(getApplicationContext(), StudentDataBase.class, "Henry")
.allowMainThreadQueries()//可以在主线程执行查询,不建议这么做
.fallbackToDestructiveMigration()//数据库改变时,强制升级时,不报错
.build();
StudentDao dao = henryDB.userDao();
dao.insert(new Student("henry0", "123", 1));
dao.insert(new Student("henry1", "456", 2));
dao.insert(new Student("henry2", "789", 3));
dao.insert(new Student("henry3", "101112", 4));
//查看全部数据
List<Student> all = dao.getall();
Log.d("Henry00", "all = " + all.toString());
Log.d("Henry00", "---------------------------------");
//查询名字为henry1的一条数据
Student henry1 = dao.findByName("henry1");
Log.d("Henry00", "henry1 查询 = " + henry1.toString());
Log.d("Henry00", "---------------------------------");
//查询id为2,3,4的数组数据
List<Student> allID = dao.getallId(new int[]{2, 3, 4});
Log.d("Henry00", "allID 查询 = " + allID.toString());
}
}
}
输出:
使用Android Studio DB Browser插件查看数据库信息
三、参考链接
Android JetPack Room 全方面解读
Android Jetpack架构组件 — Room入坑详解
Jetpack Room 使用及原理解析