Realm for Android

17171 단어 안드로이드Realm
안녕하세요 @wasabeef_kr 입니다.

Realm for Android 에 대해 이야기하고 싶습니다.



인용구 : ht tp // // 와사베에 f. jp/레아 lm-후-r 안 d로이 d/

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에도 대응하고 있습니다.

SQLite ORM과의 속도 비교






아무래도 빠른 것 같다.

Setup



공식적으로 jar가 놓여 있습니다만, Gradle이라면 다음과 같이 합니다
// build.gradle
compile 'io.realm:realm-android:0.71.+'

모델



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("[email protected]");

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은 지원되지 않습니다

  • 속성에 Enum이 있으면 Buid가 통과하지 않습니다.
    Error:(21, 8) エラー: Type io.realm.examples.intro.model.Cat.HogeType of field type is not supported
    
  • RealmObject를 GSON으로 직렬화 할 수 없습니다
  •  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를 만듭니다.

    특히 저장 위치를 ​​지정하지 않으면 다음 파일 Dir에 Realm Format으로 저장됩니다.
    /data/data/패키지 이름/files/

    아직 Version도 1.x에 가지 않았기 때문에 앞으로 기대하고 싶습니다.

    좋은 웹페이지 즐겨찾기