在 Android 中使用 Realm 作本地存儲
Android平臺有很多的orm框架可以對數據作本地存儲,比如ormlite、greenDao、SugarORM等等,這些orm框架基本都是基于sqlite的。今天我要介紹的這個數據庫Realm,是用來替代sqlite的一種解決方案,它有一套自己的數據庫存儲引擎,比sqlite更輕量級,擁有更快的速度,最重要的是跨平臺,目前已有Java,Objective C,Swift,React-Native,Xamarin這五種實現。
本文是Realm數據庫在Android中使用的一個入門級的教程,這里不對Realm與其他的orm框架的優缺點作討論。
本文學習目錄
一.環境配置
二.創建實體
三.CRUD(增刪改查操作)
四.進階用法
一.環境配置
- 在項目的build文件加上
buildscript { repositories { jcenter() } dependencies { ... classpath "io.realm:realm-gradle-plugin:1.2.0" }
- 在 app 的 build文件中加入
apply plugin: 'realm-android'
二.創建實體
Realm 支持的字段類型,除了Java提供的基本類型之外,Realm還支持 繼承了RealmObject 的對象 和 RealmList<? extends RealmObject>
這里為了方便直接使用了示例項目中的對象了。
創建一個User實體
public class User extends RealmObject {
@PrimaryKey
private String id;
private String name;
private int age;
private RealmList<User> friends;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public RealmList<User> getFriends() {
return friends;
}
public void setFriends(RealmList<User> friends) {
this.friends = friends;
}
}
細心的同學已經注意到了,我們上面創建的實體對象繼承于RealmObject ,Realm 數據實體定義需要繼承自 RealmObject類。
這里需要知道的幾點:
- @PrimaryKey 用來標識主鍵
- 默認的所有的字段都會被存儲
- 如果某個字段不需要被存儲到本地,則需在在這個字段上面加上 @Ignore 注解
三.CRUD(增刪改查操作)
數據庫的使用無非上就是增刪改查這四種操作,其中查是重點,在寫原生sql語句中這也是個難點。下面我們就來看看Realm的CRUD是怎樣的
1.添加數據
RealmConfiguration realmConfig = new RealmConfiguration
.Builder(this)
.build();
Realm realm = Realm.getInstance(realmConfig);
public void testAdd() {
initRealm();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
for (int i = 0; i < 10; i++) {
User user = realm.createObject(User.class);
user.setName("user" + i);
user.setAge(10 + i);
user.setId(UUID.randomUUID().toString());
}
showInTextView("10條數據添加成功");
}
});
}
在用Realm進行操作之前需要對Realm作相關的配置操作,Realm中所有的寫操作都必須在事務中進行,不然就會報錯, 記得在Activity的onDestory中調用realm.close()釋放資源。上面的代碼片段就創建了10個User對象。
2.查詢數據
- 查詢全部
public void testQuery() { List<User> users= realm.where(User.class).findAll(); for (User user: users) { showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge()); } }
- 條件查詢,Realm 支持以下查詢條件(來源于官網):
- between()、greaterThan()、lessThan()、greaterThanOrEqualTo() 和 lessThanOrEqualTo()
- equalTo() 和 notEqualTo()
- contains()、beginsWith() 和 endsWith()
- isNull() 和 isNotNull()
- isEmpty() 和 isNotEmpty()
以下代碼片段查詢年齡小于15的User
public void testQueryAgeLessThan15() {
List<User> users= realm.where(User.class).lessThan("age", 15).findAll();
for (User user: users) {
showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge());
}
}
-
聚合查詢,支持的聚合操作有sum,min,max,average
以下代碼片段得到所有人的平均年齡
public void testQueryAverageAge() { double age = realm.where(User.class).findAll().average("age"); textView.setText("average age:" + age); }
3.更新數據
public void testUpdate() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.where(User.class).equalTo("name", "user9").findFirst();
if (user != null) {
user.setAge(99);
user.setName("二逼青年");
}
textView.setText("更新成功");
}
});
}
4.刪除數據
以下代碼片段展示了如何刪除指定的對象
public void testDelete() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.where(User.class).equalTo("name", "user0").findFirst();
if (user != null)
user.deleteFromRealm();
textView.setText("刪除成功");
}
});
}
四.進階用法
通過前面一節的學習,我們基本學會了Realm數據庫基本的增刪改查操作。
本節來看看Realm還有什么其他用法
1.用json創建對象
在實際開發中我們和json打交道的機會比較多,所以直接從json去創建對象是十分有用的,下面的代碼片段展示了怎么去用。
private void testAddFromJson() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
String json = "{\n" +
" \"id\": \"uuid1\",\n" +
" \"name\": \"solid\",\n" +
" \"age\": 20\n" +
"}";
String jsons = "[\n" +
" {\n" +
" \"id\": \"uuid1\",\n" +
" \"name\": \"solid\",\n" +
" \"age\": 20\n" +
" },\n" +
" {\n" +
" \"id\": \"uuid2\",\n" +
" \"name\": \"jhack\",\n" +
" \"age\": 21\n" +
" },\n" +
" {\n" +
" \"id\": \"uuid3\",\n" +
" \"name\": \"tom\",\n" +
" \"age\": 22\n" +
" }\n" +
"]";
//realm.createObjectFromJson(User.class, json);
realm.createAllFromJson(User.class, jsons);
}
});
}
2.數據模型改變的處理
開發中數據模型不可能從一開始創建了,就保證后面的開發過程中不會更改,對于Realm如果其中的某個實體類改變了,而我們沒有做任何的處理,就會報錯,如果還處于應用的開發的初期,這無所謂,直接清空數據即可,但是如果應用已經發布了,我們就需要去尋找一種解決方案了。
這里的解決方案如下:
public class MyMigration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
Log.e(MainActivity.TAG, "oldVersion:" + oldVersion + " newVersion:" + newVersion);
RealmSchema schema = realm.getSchema();
if (newVersion == 2) {
schema.get("User")
.addField("desc", String.class);
}
}
@Override
public boolean equals(Object obj) {
return obj instanceof MyMigration;
}
@Override
public int hashCode() {
return super.hashCode();
}
}
realmConfig = new RealmConfiguration
.Builder(this)
.schemaVersion(2)
.migration(new MyMigration())
.build();
3.與RxJava的結合
Realm原生是支持Rxjava的,由于RxJava 是可選依賴,所以在使用的時候需要在app的build文件中添加RxJava庫的依賴,下面是使用的代碼片段。
public void testRxJava() {
realm.where(User.class).findAll()
.asObservable()
.flatMap(new Func1<RealmResults<User>, Observable<User>>() {
@Override
public Observable<User> call(RealmResults<User> users) {
return Observable.from(users);
}
})
.subscribe(new Action1<User>() {
@Override
public void call(User user) {
showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge() + " desc:" + user.getDesc());
}
});
}
這篇文章到這了,遺憾的是Realm在Windows中沒有相關的查看器,只有Mac版的,所以不能直接在Windows中查看Realm數據庫中的數據,希望官方后面會有支持吧。更多的資料請查看官方文檔。
來自:http://www.jianshu.com/p/8cb639a78975