こんにちは @wasabeef_jpです。
**Realm for Android**の話をしたいと思います。
引用:http://wasabeef.jp/realm-for-android/
Realmとは
"Realm is a mobile database: a replacement for SQLite & Core Data
Realm can save you thousands of lines of code & weeks of work,
and lets you craft amazing new user experiences."
SQLite & Core Dataを置き換えるために作られた Mobile向けのDataBase
元々、iOS向けに作られていましたが、C++で書いているので、Androidにも対応しています。
どうやら速いらしい。
Setup
公式にjarが置いてありますが、Gradleであれば以下のようにします
// build.gradle
compile 'io.realm:realm-android:0.71.+'
Models
ActiveAndroidとかSugarORMと似たように、RealmObjectを継承しておきます。
public class User extends RealmObject {
private String name;
private int age;
@Ignore
private int sessionId;
// Standard getters & setters generated by your IDE…
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 int getSessionId() { return sessionId; }
public void setSessionId(int sessionId) {
this.sessionId = sessionId;
}
}
Writes
Transactionの開始と終了は必須となります。
先ほど、定義したModelをcreateObjectに渡して
インスタンスを作ってもらい、それに対してデータの設定を行うだけとなります。
// Obtain a Realm instance
Realm realm = Realm.getInstance(this, "wasabeef.realm");
realm.beginTransaction();
// Create a new object
User user = realm.createObject(User.class);
user.setName("Wasabeef");
user.setEmail("chip@wasabeef.jp");
realm.commitTransaction();
Queries
メソッドチェインにも対応していて、とてもシンプルに書けます。
ただ、SQLiteではないので、SQL文を使うことは出来ません。
// Build the query looking at all users:
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "Wasabeef");
query.or().equalTo("name", "Chip");
// Execute the query:
RealmResults<User> resultAll = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<User> result =
realm.where(User.class)
.equalTo("name", "Wasabeef")
.or()
.equalTo("name", "Chip")
.findAll();
Sorting
Asc, Descにも対応してます。
// Query
RealmResults<User> result = realm.where(User.class).findAll();
// Asc
RealmResults<User> sortedAscending = result.sort("age");
// Desc
RealmResults<User> sortedDescending =
result.sort("age", RealmResults.SORT_ORDER_DECENDING);
Deletion
// All changes to data must happen in a transaction
realm.beginTransaction();
// remove single match
result.remove(0);
result.removeLast();
// Delete all matches
result.clear();
realm.commitTransaction()
RealmObject & RealmResults
The only rule to using Realm across threads is to remember that Realm, RealmObject or RealmResults instances cannot be passed across threads. When you want to access the same data from different threads, you should simply obtain a separate Realm instance for each thread (i.e. Realm.getInstance(this) or its cousins) and get your objects through a RealmQuery. The objects will map to the same data on disk, and will be readable & writeable from any thread!
Thread間での受け渡しの想定はしてないので
Realm.getInstance()とRealmQuery()を通して再取得する必要がある
Migration
Libraryで吸収しきれて無いので、結構めんどうくさいです。
public class Migration implements RealmMigration {
@Override
public long execute(Realm realm, long version) {
// Migrate from version 0 to version 1
if (version == 0) {
// 自分で、Tableの再構築を行う必要がある
// 省略
version++;
}
}
}
抱えてる問題点 (Latest 0.71.0)
- ModlesにSetter/Getterしか書けない
Debugなどで使いたいので、せめてtoString()くらいは書きたい
Error:(12, 19) エラー: Only getters and setters should be defined in model classes
注意:Processing class Person
- EnumはSupportしてない
プロパティにEnumがあると、Buidが通らない
Error:(21, 8) エラー: Type io.realm.examples.intro.model.Cat.HogeType of field type is not supported
- RealmObjectをGSONでSerialize出来ない
java.lang.StackOverflowError
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376)
- Migrationがイケてない
本当にイケてない、いや他のORMとかの考え方が綺麗なだけのかも。
Realm Browser
Realm DataBaseをGUIで閲覧・編集できるツールも用意されてます。
雑感
Realmは、SQLiteを使っていません。
独自にFormatで、DataBaseを作成してます。
特に保存先を指定しなければ、以下のFile DirにRealm Formatで保存されます。
/data/data/パッケージ名/files/
まだVersionも1.xに行っていないので、今後に期待したいと思ってます。