📜  Android 内部的 Room 是如何工作的?(1)

📅  最后修改于: 2023-12-03 14:59:16.189000             🧑  作者: Mango

Android 内部的 Room 是如何工作的?

简介

Room 是 Google 推出的一个用于 SQLite 数据库操作的 ORM 框架,不同于传统 SQL 操作数据库的方式,Room 采用了在编译时生成 SQL 的方式来进行实体类与数据库表的映射,大大减少了开发者犯错的概率,增加了程序的稳定性。

Room 的组成

Room 主要由三个组件构成:DatabaseEntityDAO

Database

Database 是 Room 的最顶层容器,负责管理整个操作数据库的流程,包括建立数据库、创建数据表等操作。

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

官方推荐将 Database 定义为一个抽象类,同时继承自 RoomDatabase,我们需要在 Database 的注解中提供数据库涉及到的所有 Entity 和版本号。当然,如果我们需要多个 Entity,只需要在 entities 数组中加入多个实体类即可。

Entity

Entity 是 Room 的核心,负责定义表与表的列,同时将表的列映射至实体类的属性上。

@Entity
public class User {
    @PrimaryKey(autoGenerate = true)
    public long id;

    @ColumnInfo(name = "name")
    public String name;

    @ColumnInfo(name = "age")
    public int age;
}

在 Entity 中我们需要指定表的名称,同时也需要指定一个主键。如果需要自动生成主键,我们需要给主键添加 autoGenerate = true 的注解,当然,如果偏偏要使用固定值作为主键,自行打草稿实现即可。

DAO

DAO 是数据访问对象(Data Access Object)的缩写。作为 Room 数据库相关操作的承载者,我们要在 DAO 中定义所有相关的 SQL 操作,比如查询、更新、删除等等。这所有的操作都是通过 Room 在编译期间生成的。

@Dao
public interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(User user);

    @Query("SELECT * FROM User")
    List<User> getAllUser();
}

在 DAO 中我们用注解来声明需要的 SQL 操作,其中关键字 Query 代表查询操作,Insert 代表插入操作等等。注解中的 SQL 语句同样也使用了类似占位符的方式,可以直接使用 Java 参数进行替换。

Room 工作流程

当我们使用 Room 进行数据操作时,大概的流程如下:

  1. 程序发起 SQL 请求
  2. Room 通过编译期间生成的代码将 SQL 请求编译为 SQLite 的底层查询语句
  3. 程序通过 SQLite 对数据库进行操作并返回结果
Room 底层实现

Room 的底层查询语句和 Android 自带 SQLiteOpenHelper 开发方式有一些不同。在使用普通数据库开发方式的场景下,我们通常需要编写 SQL 语句,如下:

String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
                + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + NAME + " VARCHAR(20), "
                + AGE + " INTEGER)";
database.execSQL(sql);

而使用 Room 则会自动生成对应的 SQL 语句,如下:

CREATE TABLE IF NOT EXISTS User (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    name TEXT, 
    age INTEGER NOT NULL)

由此可见,使用 Room 进行数据库操作,开发人员无需关心 SQL 语句的编写,而是要关注简化后的 API 调用。在 Room 的实现过程中,主要使用了以下技术:

  1. Annotation Processing: 用于在编译期间生成编译期代码,细节请自行搜索
  2. SQLite with Android-specific modifications: Android Framework 对 SQLite 进行的轻微修改,以适应 Android 应用操作
  3. SQLDelight: Square 公司开源的 SQL 安全库,简化了 SQL 编写流程
总结

在 Android 开发中,针对数据库操作使用 Room 作为 ORM 框架非常明智。Room 可以帮助我们抽象出所有的 SQL 操作,避免了开发者容易犯错的地方,同时简化了数据库操作的 API 调用。