Android 官方数据库Room --- 配置

本文介绍如何使用Android Room持久性库定义实体、表及关系。包括配置依赖、定义实体类、设置主键、索引和唯一性约束等核心概念。

源文档链接

工程配置

implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

// RxJava support for Room (use 1.1.0-alpha3 for latest alpha)
implementation "android.arch.persistence.room:rxjava2:1.0.0"

表定义

定义Entity

默认情况,Room会为使用了@Entity注解的类中的每个属性建列,可以使用@Ignore忽略某个属性

@Entity
class User {
    @PrimaryKey
    public int id;

    public String firstName;
    public String lastName;

    @Ignore
    Bitmap picture;
}

对于属性,Room必须能够使用,可以直接设置为public,后者提供setter/getter方法,使用set/get时,是使用的JavaBean中的约定

注意

实体类可以有无参构造器,也可以使用有参构造器(此时,对应的参数和属性的名字和类型要一一对应)

使用PrimariKey

每个Entity必须至少定义一个PrimaryKey的属性;想要使用Room自动定义ID时,可以使用PrimaryKeyautoGenerate属性;如果使用复合主键,可以使用EntityprimaryKey属性

如:

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

    @Ignore
    Bitmap picture;
}

默认情况,Room使用类名作为表名,可以使用EntitytableName进行定义

@Entity(tableName = "users")
class User {
    ...
}

注意

SQLite中的表名不区分大小写

tableName类似,Room使用属性的名字作为表中的列名,可以使用@ColumnInfoname进行定义

@Entity(tableName = "users")
class User {
    @PrimaryKey
    public int id;

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

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

    @Ignore
    Bitmap picture;
}
注释索引和唯一性
  1. 如果需要添加索引加快查询速度,可以使用Entity中的indices属性,指定索引(复合索引)

    @Entity(indices = {@Index("name"),
            @Index(value = {"last_name", "address"})})
    class User {
        @PrimaryKey
        public int id;
    
        public String firstName;
        public String address;
    
        @ColumnInfo(name = "last_name")
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
  2. 为单个属性(多个属性)设置唯一性

    @Entity(indices = {@Index(value = {"first_name", "last_name"},
            unique = true)})
    class User {
        @PrimaryKey
        public int id;
    
        @ColumnInfo(name = "first_name")
        public String firstName;
    
        @ColumnInfo(name = "last_name")
        public String lastName;
    
        @Ignore
        Bitmap picture;
    }
    
定义对象关系

SQLite是关系型数据库,可以指定对象之间的关系。Room禁止实体对象之间的互相引用。

虽然不可以直接引用,Room允许使用外键

User和Book通过ForeignKey建立关系

@Entity(foreignKeys = @ForeignKey(entity = User.class,
                                  parentColumns = "id",
                                  childColumns = "user_id"))
class Book {
    @PrimaryKey
    public int bookId;

    public String title;

    @ColumnInfo(name = "user_id")
    public int userId;
}

针对上述代码,可以使用ForeginKey中的onDelete = CASCADE来告诉SQLite,当删除一个User时,那么这个User对应的所有Book也会同时删除

注意

SQLite处理@Insert(onConflict = Replace)会有一系列REMOVEREPLACE操作,而不是一个UPDATE操作。这个方法中的REPLACE操作中的冲突值可能影响外键,SQLite documentation

创建嵌套对象

当对象内部使用引用对象作为属性时,可以使用@Embedded来对该对象进行分解,再一次存入到对应的列中

class Address {
    public String street;
    public String state;
    public String city;

    @ColumnInfo(name = "post_code")
    public int postCode;
}

@Entity
class User {
    @PrimaryKey
    public int id;

    public String firstName;

    @Embedded
    public Address address;
}

上述的代码建成的user表中,会有6个字段 – id,firstName,street,state,city,post_code

注意

Embedded属性可以包括其他的嵌入属性

如果实体中相同类型的属性具有多个,可以使用prefix属性来标明唯一性。Room会在对应的属性前加入prefix的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值