Android -【 開(kāi)源庫】數據庫 Realm 的(de)基本使用
2023/7/22 9:00:00 【次浏覽】 本站
簡介
Realm 是一個(gè) MVCC (多版本并發控制)數據庫,由Y Combinator公司在2014年(nián)7月(yuè)發布一款支持運行在手機(jī)、平闆和(hé)可穿戴設備上(shàng)的(de)嵌入式數據庫,目标是取代 SQLite。Realm 本質上(shàng)是一個(gè)嵌入式數據庫,他(tā)并不是基于 SQLite 所構建的(de)。它擁有(yǒu)自(zì)己的(de)數據庫存儲引擎,可以高(gāo)效且快速地(dì)完成數據庫的(de)構建操作(zuò)。和(hé) SQLite 不同,它允許你(nǐ)在持久層直接和(hé)數據對(duì)象工(gōng)作(zuò)。在它之上(shàng)是一個(gè)函數式風(fēng)格的(de)查詢 API,衆多的(de)努力讓它比傳統的(de)SQLite 操作(zuò)更快 。
GitHub 地(dì)址:realm-java
優點
易用
Ream 不是在SQLite基礎上(shàng)的(de)ORM,它有(yǒu)自(zì)己的(de)數據查詢引擎。并且十分容易使用。
快速
由于它是完全重新開(kāi)始開(kāi)發的(de)數據庫實現(xiàn),所以它比任何的(de)ORM速度都(dōu)快很(hěn)多,甚至比SLite速度都(dōu)要快。
跨平台
Realm 支持 iOS & OS X (Objective‑C & Swift) & Android。我們可以在這(zhè)些平台上(shàng)共享Realm數據庫文(wén)件(jiàn),并且上(shàng)層邏輯可以不用任何改動的(de)情況下(xià)實現(xiàn)移植。
高(gāo)級
Ream支持加密,格式化(huà)查詢,易于移植,支持JSON,流式api,數據變更通(tōng)知等高(gāo)級特性
可視(shì)化(huà)
Realm 還(hái)提供了一個(gè)輕量級的(de)數據庫查看(kàn)工(gōng)具,在Mac Appstore 可以下(xià)載“Realm Browser”這(zhè)個(gè)工(gōng)具,開(kāi)發者可以查看(kàn)數據庫當中的(de)內(nèi)容,執行簡單的(de)插入和(hé)删除數據的(de)操作(zuò)。
使用
1. 添加依賴
在 project 的(de) build 中加入依賴
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:2.2.1"
}
}
在 module 中加入
apply plugin: 'realm-android'
1
2. 創建 model
創建一個(gè) User 類,需要繼承 RealmObject 。支持public, protected和(hé) private的(de)類以及方法
public class User extends RealmObject {
private String name;
private int age;
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;
}
}
除了直接繼承于 RealmObject 來(lái)聲明(míng) Realm 數據模型之外(wài),還(hái)可以通(tōng)過實現(xiàn) RealmModel 接口并添加 @RealmClass 修飾符來(lái)聲明(míng)。
@RealmClass
public class User implements RealmModel {
...
}
3. 初始化(huà)
使用默認配置:
Realm.init(this);
Realm mRealm = Realm.getDefaultInstance();
這(zhè)時(shí)候會創建一個(gè)叫做 default.realm的(de)Realm文(wén)件(jiàn),一般來(lái)說(shuō),這(zhè)個(gè)文(wén)件(jiàn)位于/data/data/包名/files/。通(tōng)過realm.getPath()來(lái)獲得該Realm的(de)絕對(duì)路(lù)徑。
注意:模拟器(qì)上(shàng)運行時(shí),Realm.getDefaultInstance()抛出異常,真機(jī)上(shàng)沒問(wèn)題
當然,我們還(hái)可以使用 RealmConfiguration 來(lái)配置 Realm
RealmConfiguration config = new RealmConfiguration.Builder()
.name("myrealm.realm") //文(wén)件(jiàn)名
.schemaVersion(0) //版本号
.build();
Realm realm = Realm.getInstance(config);
4. 關閉 Realm
記得使用完後,在 onDestroy 中關閉 Realm
@Override
protected void onDestroy() {
super.onDestroy();
// Close the Realm instance.
realm.close();
}
5. 版本升級
當數據結構發生(shēng)變化(huà)是,需要升級數據庫。對(duì)于Realm來(lái)說(shuō),數據庫升級就是遷移操作(zuò),把原來(lái)的(de)數據庫遷移到新結構的(de)數據庫。
例1:User類發生(shēng)變化(huà),移除age,新增個(gè)@Required的(de)id字段。
User版本:version 0
String name;
int age;
User版本:version 1
@Required
String id;
String name;
創建遷移類 CustomMigration,需要實現(xiàn)RealmMigration接口。執行版本升級時(shí)的(de)處理(lǐ):
/**
* 升級數據庫
*/
class CustomMigration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
RealmSchema schema = realm.getSchema();
if (oldVersion == 0 && newVersion == 1) {
RealmObjectSchema personSchema = schema.get("User");
//新增@Required的(de)id
personSchema
.addField("id", String.class, FieldAttribute.REQUIRED)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicReal
mObject obj) {
obj.set("id", "1");//為(wèi)id設置值
}
})
.removeField("age");//移除age屬性
oldVersion++;
}
}
}
使用Builder.migration升級數據庫,将版本号改為(wèi)1(原版本号:0)。當Realm發現(xiàn)新舊(jiù)版本号不一緻時(shí),會自(zì)動使用該遷移類完成遷移操作(zuò)。
RealmConfiguration config = new RealmConfiguration.Builder()
.name("myrealm.realm") //文(wén)件(jiàn)名
.schemaVersion(1)
.migration(new CustomMigration())//升級數據庫
.build();
6. 增
寫入操作(zuò)需要在事(shì)務中進行,可以使用executeTransaction方法來(lái)開(kāi)啓事(shì)務。
使用executeTransaction方法插入數據
mRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.createObject(User.class);
user.setName("Gavin");
user.setAge(23);
}
});
注意:如果在UI線程中插入過多的(de)數據,可能會導緻主線程擁塞。
使用copyToRealmOrUpdate或copyToRealm方法插入數據
當Model中存在主鍵的(de)時(shí)候,推薦使用copyToRealmOrUpdate方法插入數據。如果對(duì)象存在,就更新該對(duì)象;反之,它會創建一個(gè)新的(de)對(duì)象。若該Model沒有(yǒu)主鍵,使用copyToRealm方法,否則将抛出異常。
final User user = new User();
user.setName("Jack");
user.setId("2");
mRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(user);
}
});
使用executeTransactionAsync該方法會開(kāi)啓一個(gè)子(zǐ)線程來(lái)執行事(shì)務,并且在執行完成後進行結果通(tōng)知。
RealmAsyncTask transaction = mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.createObject(User.class);
user.setName("Eric");
user.setId("4");
}
});
注意:如果當Acitivity或Fragment被銷毀時(shí),在OnSuccess或OnError中執行UI操作(zuò),将導緻程序奔潰 。用RealmAsyncTask .cancel();可以取消事(shì)務
7. 删
使用deleteFromRealm()
//先查找到數據
final RealmResults userList = mRealm.where(User.class).findAll();
mRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
userList.get(0).deleteFromRealm();
}
});
使用deleteFromRealm(int index)
mRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
userList.deleteFromRealm(0);
}
});
8. 改
mRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
//先查找後得到User對(duì)象
User user = mRealm.where(User.class).findFirst();
user.setAge(26);
}
});
9. 查
findAll ——查詢
RealmResults userList = mRealm.where(User.class).findAll();
1
findAllAsync——異步查詢
RealmResults userList = mRealm.where(User.class)
.equalTo("name", "Kevin")
.findAllAsync();
findFirst ——查詢第一條數據
User user2 = mRealm.where(User.class).findFirst();
equalTo ——根據條件(jiàn)查詢
RealmResults userList = mRealm.where(User.class)
.equalTo("name", "Kevin").findAll();
equalTo ——多條件(jiàn)查詢
RealmResults userList = mRealm.where(User.class)
.equalTo("name", "Kevin").findAll();
RealmResults userList = user5.where()
.equalTo("dogs.name", "二哈").findAll();
手機(jī)掃碼查看(kàn)當前文(wén)章(zhāng):