在 Android 中使用 Realm 作本地存儲

tbc 8年前發布 | 30K 次閱讀 Realm 安卓開發 Android開發 移動開發

Android平臺有很多的orm框架可以對數據作本地存儲,比如ormlite、greenDao、SugarORM等等,這些orm框架基本都是基于sqlite的。今天我要介紹的這個數據庫Realm,是用來替代sqlite的一種解決方案,它有一套自己的數據庫存儲引擎,比sqlite更輕量級,擁有更快的速度,最重要的是跨平臺,目前已有Java,Objective C,Swift,React-Native,Xamarin這五種實現。

本文是Realm數據庫在Android中使用的一個入門級的教程,這里不對Realm與其他的orm框架的優缺點作討論。

本文學習目錄

一.環境配置

二.創建實體

三.CRUD(增刪改查操作)

四.進階用法

一.環境配置

  1. 在項目的build文件加上
    buildscript {
     repositories {
         jcenter()
     }
     dependencies {
         ...
         classpath "io.realm:realm-gradle-plugin:1.2.0"
     }
  2. 在 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

 

 本文由用戶 tbc 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!