Android Room持久化库

前言

简化过的 Room 提供了一个对象映射抽象层,以便在使用SQLite强大功能的同时能够更加流畅的访问数据库。

Room 中有三个主要的组件:

  • Database: 通过该组件你可以创建持有操作数据库的对象。注解定义了实体的列表,类的内容定义了从数据库中获取数据的对象(DAO),同时它也是底层连接的主要入口。

注: 此组件一个继承自RoomDatabase的抽象类。代码中可以通过调用Room.databaseBuilder或Room.inMemoryDatabaseBuilder()来获得一个实例。

  • Entity: 此组件表示持有数据库中的一个表的类,对应到表的一行数据, 除非有显式的@Ignore注解,实体中的每个属性都将被持久化到数据库里面。

  • DAO: 此组件是 Room 的主要组件, 作为数据访问对象(DAO)的类或接口。负责定义访问数据库的一系列CURD方法。

注: 使用@Database注解的类必须包含一个0参数的,返回类型为@Dao注解过的类的抽象方法,Room会在编译时生成这个类的实现。

导入到项目

使用Android Studio 2.3或更高的版本

  • 往项目根目录的build.grdle添加如下
1
2
3
4
5
6
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}

注: 编译过程可能遇到链接不到maven的问题, 将maven { url ‘https://maven.google.com‘ } 换成 maven { url “https://dl.google.com/dl/android/maven2/"} 便可

  • app的build.gradle添加如下依赖库
1
2
compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5"

代码示例

声明数据表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@Entity(tableName = "contacts")
public class Contact {
@PrimaryKey
@ColumnInfo(name = "uid")
private final String mId;
@Nullable
@ColumnInfo(name = "user_name")
private final String mUserName;
@Ignore
public Contact(@NonNull String userName){
this(UUID.randomUUID().toString(),userName);
}
public Contact(@NonNull String id, @NonNull String userName) {
mId = id;
mUserName = userName;
}
@NonNull
public String getId() {
return mId;
}
@Nullable
public String getUserName() {
return mUserName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Contact contact = (Contact) o;
return Objects.equal(mId, contact.mId) &&
Objects.equal(mUserName, contact.mUserName);
}
@Override
public int hashCode() {
return Objects.hashCode(mId, mUserName);
}
@Override
public String toString() {
return "Contact with userName " + mUserName;
}
}

声明数据访问对象的CURD操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Dao
public interface ContactsDao {
@Query("SELECT * FROM Contacts")
List<Contact> getContacts();
@Query("SELECT * FROM Contacts WHERE uid = :uId")
Contact getContactById(String uId);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertContact(Contact contact);
@Update
int updateContact(Contact contact);
@Query("DELETE FROM Contacts WHERE uid = :uId")
int deleteContactById(String uId);
@Query("DELETE FROM Contacts")
void deleteContact();
}

创建持有数据库操作的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Database(entities = {Contact.class}, version = 1)
public abstract class ContactDatabase extends RoomDatabase{
private static ContactDatabase INSTANCE;
public abstract ContactsDao contactDao();
private static final Object sLock = new Object();
public static ContactDatabase getInstance(Context context) {
synchronized (sLock) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
ContactDatabase.class, "Contacts.db")
.build();
}
return INSTANCE;
}
}
}

获得数据库实例,简单的添加几条记录,然后查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
ContactDatabase database = ContactDatabase.getInstance(getContext());
mDataSource = ContactsLocalDataSource.getInstance(new AppExecutors(), database.contactDao());
for (int i = 0; i < 5; i++) {
mDataSource.saveContact(new Contact("" + (i + 1), "学生" + (i + 1)));
}
mDataSource.getContact("2", new ContactsDataSource.GetContactCallback() {
@Override
public void onContactLoaded(Contact contact) {
Log.e("aaa", contact.toString());
}
@Override
public void onDataNotAvailable() {
}
});
mDataSource.getContacts(new ContactsDataSource.LoadContactsCallback() {
@Override
public void onContactsLoaded(List<Contact> contacts) {
for (Contact contact : contacts) {
Log.e("aaa", contact.toString());
// Log.e("aaa", contact.getId());
}
}
@Override
public void onDataNotAvailable() {
Log.e("aaa", "nodata");
}
});

更多细节请参见 Room Persistence Library

打赏作者