Edited at

ポストSQLiteのRealmを触ってみる

More than 3 years have passed since last update.


Realmって?

簡潔に言うと「Mobile向けNoSQL系データベース」です。

特にこのRealmは、SQLite(Android)とCoreData(iOS)を置き換えることを目的として開発されているとのこと。大きく分けて、Java用とCOCOA用とが用意されてます。

一番の特徴は、その圧倒的なパフォーマンスのようです。確かにこの公式サイトのデモは驚きました。

他にもいろいろ優れた点があるようなので、興味ある方は公式サイト見るといいと思います。

とにかく触ってみるのが一番だと思ったので、SQLiteとの比較とか無しにコードを書いてみました。


Realm for Java

Androidアプリで使うために必要な要件です。


  • AndroidStudio 0.8.6以上

  • 最新のAndroidSDK

  • JDK 7以上

  • API Level9以上


インストール方法

AndroidStudioであれば、dependencyに書いてもいいしダウンロードしたJarを入れてもいいようです。

Eclipseでも使えるようですが、だいぶ面倒くさい手順を踏まないといけないので、必要な人は公式サイト見てください。

Mavenの場合


  1. build.gradleに書く(※ repositoriesにはjcenterを使う)


build.gradle

compile 'io.realm:realm-android:0.73.1'


Jarの場合



  1. ここからリリースパッケージをダウンロードする

  2. libsにrealm-VERSION.jarをコピー

  3. build.gradleに書く


build.gradle

compile files('libs/realm-VERSION.jar')



使ってみる


モデルクラスを作る

RealmObjectのサブクラスを作るだけ。

GetterとSetterは自分で書かないといけないらしいけど、「AndroidStudioのGenerator使えば簡単だよね」ってことみたいです。

使える型は、boolean, short, ìnt, long, float, double, String, Date, byte[]です。


TestModel.java

public class TestModel extends RealmObject {

private String name;
private String favorite;

public void setName(String name) {
this.name = name;
}

public void setFavorite(String favorite) {
this.favorite = favorite;
}

public String getName() {
return name;
}

public String getFavorite() {
return favorite;
}
}



Writeしてみる

追加、変更、削除をするときは必ずTransaction処理の中で行う必要があるとのこと。

特に新しくデータを作成するときは、createObject()でインスタンスを生成するのがルールみたいです。


MainActivity.java

    Realm realm = Realm.getInstance(this);

realm.beginTransaction();

TestModel model = realm.createObject(TestModel.class);
model.setName("name 1");
model.setFavorite("coffee");

realm.commitTransaction();



Queryを発行してみる

公式サイトに書いてあるけど、ちょっと以下の点に注意しないといけない。


All fetches (including queries) are lazy in Realm, and the data is never copied.


特に取得した結果はコピーじゃなくてオブジェクトの参照が返ってくるから、変更したり削除したりする場合は、前述したように必ずTransaction内でやらないとダメなようです。

メソッドチェーンでスッキリ書けるのは、気持ちいい。


MainActivity.java

// 普通の書き方

RealmQuery<TestModel> query = realm.where(TestModel.class);
query.equalTo("name", "name 1");
RealmResults<TestModel> result1 = query.findAll();

// メソッドチェーンを使える
RealmResults<TestModel> result2 = realm.where(TestModel.class)
.equalTo("name", "name 1")
.findAll();



Auto-Refresh機能を試す

面白いなーと思ったのが、同じLooper内(通常はUIスレッド)でRealmのインスタンスと更新処理が行われた場合に、自動的にインスタンスが最新版のデータを参照するようになるようです。

原文の一部抜粋です。


If a Realm instance is contained in a thread that is associated with a Looper (the UI thread is by default) then the Realm instance comes with an auto-refresh feature. This means that the Realm instance will be automatically updated to the latest version on every occurrence of the event loop.


試しに以下のような実験をしてみました。

setAutoRefresh(true)で有効化させてます。


  1. 初期化ボタンを押すと新規作成した"coffee"のデータをTextViewにセットする

  2. 更新ボタンを押すと1のデータを"green tea"に書き換えてTextViewにセットする

上記を動かしてみると、キャプチャのようになりました。

同じTestModel(RealmObject)のインスタンスを使ってるのに、ちゃんとデータの中身が更新されてるのが分かりますね。

すごい、これは便利ですね。


MainActivity.java

    private Realm mRealm;

private TestModel mModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mRealm = Realm.getInstance(this);
mRealm.setAutoRefresh(true);

findViewById(R.id.update_button1).setOnClickListener(this);
findViewById(R.id.update_button2).setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.update_button1:
mRealm.beginTransaction();
mModel = mRealm.createObject(TestModel.class);
mModel.setName("name 1");
mModel.setFavorite("coffee");
mRealm.commitTransaction();
break;
case R.id.update_button2:
mRealm.beginTransaction();
mModel.setFavorite("green tea");
mRealm.commitTransaction();
break;
}
setTextView();
}

private void setTextView() {
((TextView) findViewById(R.id.label_view)).setText(mModel.getFavorite());
}


realm_refresh1.png realm_refresh2.png realm_refresh3.png


感想

コードの書き方とかは、ActiveAndroidとかと同じようなイメージで書けるので、AndroidでORMのライブラリ使ったことある人は、かなりすんなり使えそうだなと思いました。公式サイトのドキュメントは細かく書かれているし、いくつかの機能の説明ではサンプルソースもありました。これならプライベート・プロジェクトなどで、試しながら使っていけそうな気がしました。

今回は超基本的な部分しか触ってないけど、書いていて気持ちがいいのもあり、引き続きもっといろんな機能を試してみたいです。


参考にしたサイト