realm 使用总结

Realm,为移动设备而生!替代 SQLite 和 Core Data。为你省下数周的时间和数千行的代码,帮你创造出更棒的用户体验。--Realm官网

realm 使用总结_第1张图片
benchmarks-android.001.png

realm 使用总结_第2张图片
benchmarks-android.002.png

realm 使用总结_第3张图片
benchmarks-android.003.png

优势

Realm 并不是基于 Core Data ,也不是基于 SQLite 所构建的。它拥有自己的数据库存储引擎,可以高效且快速地完成数据库的构建操作。

  • Realm 比使用 SQLite 要快,比ORM要快很多。
  • 简单。通过标注和对象操作实现数据操作。
  • 版本升级时,数据迁移成本很低。
  • 与rxjava、retrofit等Library有很好的交互。

使用

  • Model create
public class User extends RealmObject {
    @PrimaryKey
    private String          name;
    @Required
    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; }
}
  • Transaction blocks
realm.beginTransaction();
User user = realm.createObject(User.class);

//  ...

realm.cancelTransaction();
//---------
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        User user = realm.createObject(User.class);
        user.setName("John");
        user.setEmail("[email protected]");
    }
});

  • Write
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("[email protected]");
realm.commitTransaction();
////////
User user = new User("John");
user.setEmail("[email protected]");

// Copy the object to Realm. Any further changes must happen on realmUser
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();
  • Queries
// Build the query looking at all users:
RealmQuery query = realm.where(User.class);

// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");

// Execute the query:
RealmResults result1 = query.findAll();

// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults result2 = realm.where(User.class)
                                  .equalTo("name", "John")
                                  .or()
                                  .equalTo("name", "Peter")
                                  .findAll();
// sort                              
RealmResults result = realm.where(User.class).findAll();
result = result.sort("age"); // Sort ascending
result = result.sort("age", Sort.DESCENDING);                                  
  • Deletion
// obtain the results of a query
final RealmResults results = realm.where(Dog.class).findAll();

// All changes to data must happen in a transaction
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        // remove single match
        results.deleteFirstFromRealm();
        results.deleteLastFromRealm();

        // remove a single object
        Dog dog = results.get(5);
        dog.deleteFromRealm();

        // Delete all matches
        results.deleteAllFromRealm();
    }
});

  • Migrations
RealmConfiguration config = new RealmConfiguration.Builder(context)
    .schemaVersion(2) // Must be bumped when the schema changes
    .migration(new MyMigration()) // Migration to run instead of throwing an exception
    .build()
// Example migration adding a new class
RealmMigration migration = new RealmMigration() {
  @Override
  public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

     // DynamicRealm exposes an editable schema
     RealmSchema schema = realm.getSchema();

     // Migrate to version 1: Add a new class.
     // Example:
     // public Person extends RealmObject {
     //     private String name;
     //     private int age;
     //     // getters and setters left out for brevity
     // }
     if (oldVersion == 0) {
        schema.create("Person")
            .addField("name", String.class)
            .addField("age", int.class);
        oldVersion++;
     }

     // Migrate to version 2: Add a primary key + object references
     // Example:
     // public Person extends RealmObject {
     //     private String name;
     //     @PrimaryKey
     //     private int age;
     //     private Dog favoriteDog;
     //     private RealmList dogs;
     //     // getters and setters left out for brevity
     // }
     if (oldVersion == 1) {
        schema.get("Person")
            .addField("id", long.class, FieldAttribute.PRIMARY_KEY)
            .addRealmObjectField("favoriteDog", schema.get("Dog"))
            .addRealmListField("dogs", schema.get("Dog"));
        oldVersion++;
     }
  }
}

减少realm增加包的大小

在默认情况下,使用realm会将安装包增大几M,这是因为realm会默认将所有架构(ARM7, ARMv7, ARM64, x86, MIPS)下so文件打入安装包,如果使用的app仅是支持某些架构,就需要对其so进行裁剪。

packagingOptions {
    exclude "lib/armeabi/librealm-jni.so"
    exclude "lib/arm64-v8a/librealm-jni.so"
    exclude "lib/mips/librealm-jni.so"
    exclude "lib/x86/librealm-jni.so"
    exclude "lib/x86_64/librealm-jni.so"
}

splits {
    abi {
        enable true
        reset()
        include 'armeabi-v7a'
    }
}

注意事项

  • Realm object 和Java object
    Java object 包含所有对象所有数据。Realm object不包含数据,只有对数据库位置的一个引用,这样可以保证使数据保持最新,同事保证减少内存的使用。
    两者转换 Realm.copyToRealm()和“Realm.copyFromRealm()”

  • 同一Realm实例只能在一个线程中使用。

  • 所有的操作必须在事务中操作

最佳使用

  • model类使用get/set方法,外部类使用get方法或者model属性。


    realm 使用总结_第4张图片
    realmobject-watch-panel.png

    realm 创建了 proxy 对象,同时复写了get 和set方法。

  • 配合rxjava中,所有操作都在io线程组进行, Realm实例当前使用,当次获取 Realm.getDefaultInstance(), 结束后 realm.close
  • stetho-realm 。在chrome中查看Realm数据库。

引用

  1. Realm Doc
  2. Realm Java的学习、应用、总结

你可能感兴趣的:(realm 使用总结)