谷歌官方Android应用架构库——Room 持久化库

本文详细介绍了谷歌官方的Android应用架构库——Room,它提供了一个SQLite的抽象层,简化了数据库访问。文章讲解了Room的组件如Database、Entity和DAO,以及如何处理主键、索引、关系、数据访问、类型转换和数据库迁移。还展示了如何通过DAO进行数据操作,并提供了使用LiveData和RxJava的示例。
摘要由CSDN通过智能技术生成

架构库版本:1.0.0 Alpha 2 - June 2, 2017

Room提供了一个SQLite之上的抽象层,使得在充分利用SQLite功能的前提下顺畅的访问数据库。

对于需要处理大量结构化数据的App来说,把这些数据做本地持久化会带来很大的好处。常见的用例是缓存重要数据块。这样当设备无法连网的时候,用户仍然可以浏览内容。而用户对内容做出的任何改动都在网络恢复的时候同步到服务端。

核心framework内置了对SQL的支持。虽然这些API很强大,但是都很低级,使用起来很花时间和精力:

  • 没有编译时的SQL查询检查机制。当数据表发生改变的时候,需要手动更新受影响的SQL查询。这个过程既耗时又容易出错。

  • 需要写很多公式化的代码在SQL查询与Java对象之间转换。

Room处理了这些相关的事情,同时提供了SQLite之上的抽象层。

Room中有三个主要的组件:

  • Database:你可以用这个组件来创建一个database holder。注解定义实体的列表,类的内容定义从数据库中获取数据的对象(DAO)。它也是底层连接的主要入口。

这个被注解的类是一个继承RoomDatabase的抽象类。在运行时,可以通过调用Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder()来得到它的实例。

  • Entity:这个组件代表一个持有数据库的一个表的类。对每一个entity,都会创建一个表来持有这些item。你必须在Database类中的entities数组中引用这些entity类。entity中的每一个field都将被持久化到数据库,除非使用了@Ignore注解。

注:实体可以有一个空构造函数(如果DAO类可以访问每个持久化字段),或者一个构造函数的参数包含与实体中的字段匹配的类型和名称。Romm还可以使用全部或部分构造函数,例如只接收一些字段的构造函数。

  • DAO:这个组件代表一个作为Data Access Objec的类或者接口。DAO是Room的主要组件,负责定义查询(添加或者删除等)数据库的方法。使用@Database注解的类必须包含一个0参数的,返回类型为@Dao注解过的类的抽象方法。Room会在编译时生成这个类的实现。

注:通过DAO而不是query builders或者直接的query语句来处理数据库,可以把数据库的各个部分分离开来。而且DAO还可以让你轻松的使用假的database来测试app。

这些组件以及它们与app其余部分之间的关系如图1:

room_architecture

下面是一个只有一个entity和一个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();
}

创建了上面的文件之后,可以使用下面的代码来得到database的实例了:

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();

在实例化AppDatabase对象的时候应该遵循单例模式,因为每个Database实例都是相当耗费的,而且也很少需要多个实例。

Entities

当一个类用@Entity注解并且被@Database注解中的entities属性所引用,Room就会在数据库中为那个entity创建一张表。

默认Room会为entity中定义的每一个field都创建一个column。如果一个entity中有你不想持久化的field,那么你可以使用@Ignore来注释它们,如下面的代码所示:

@Entity
class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

要持久化一个field,Room必须有获取它的渠道。你可以把field写成public,也可以为它提供一个setter和getter。如果你使用setter和getter的方式,记住它们要基于Room的Java Bean规范。

Primary key

每个entity必须至少定义一个field作为主键(primary key)。即使只有一个field,你也必须用@PrimaryKey注释这个field。如果你想让Room为entity设置自增ID,你可以设置@PrimaryKey的autoGenerate属性。如果你的entity有一个组合主键,你可以使用@Entity注解的primaryKeys属性,具体用法如下:

@Entity(primaryKeys = {
  "firstName", "lastName"})
class User {
    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

Room默认把类名作为数据库的表名。如果你想用其它的名称,使用@Entity注解的tableName属性,如下:

@Entity(tab
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值