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の場合
- build.gradleに書く(※ repositoriesにはjcenterを使う)
compile 'io.realm:realm-android:0.73.1'
Jarの場合
- ここからリリースパッケージをダウンロードする
- libsにrealm-VERSION.jarをコピー
- build.gradleに書く
compile files('libs/realm-VERSION.jar')
使ってみる
モデルクラスを作る
RealmObjectのサブクラスを作るだけ。
GetterとSetterは自分で書かないといけないらしいけど、「AndroidStudioのGenerator使えば簡単だよね」ってことみたいです。
使える型は、boolean, short, ìnt, long, float, double, String, Date, byte[]
です。
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()
でインスタンスを生成するのがルールみたいです。
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内でやらないとダメなようです。
メソッドチェーンでスッキリ書けるのは、気持ちいい。
// 普通の書き方
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)
で有効化させてます。
- 初期化ボタンを押すと新規作成した"coffee"のデータをTextViewにセットする
- 更新ボタンを押すと1のデータを"green tea"に書き換えてTextViewにセットする
上記を動かしてみると、キャプチャのようになりました。
同じTestModel(RealmObject)のインスタンスを使ってるのに、ちゃんとデータの中身が更新されてるのが分かりますね。
すごい、これは便利ですね。
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());
}
感想
コードの書き方とかは、ActiveAndroidとかと同じようなイメージで書けるので、AndroidでORMのライブラリ使ったことある人は、かなりすんなり使えそうだなと思いました。公式サイトのドキュメントは細かく書かれているし、いくつかの機能の説明ではサンプルソースもありました。これならプライベート・プロジェクトなどで、試しながら使っていけそうな気がしました。
今回は超基本的な部分しか触ってないけど、書いていて気持ちがいいのもあり、引き続きもっといろんな機能を試してみたいです。