自(zì)強不息    厚德載物(wù)

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):

Android -【 開(kāi)源庫】數據庫 Realm 的(de)基本使用

如本網轉載稿涉及版權等問(wèn)題,請作(zuò)者見稿後在兩周內(nèi)速來(lái)電(diàn)與我們聯系, 詳見版權聲明(míng)

  上(shàng)一篇:Android開(kāi)源庫——xUtils框架

 下(xià)一篇:騰訊x5內(nèi)核TBS服務集成