Realm,为移动设备而生!替代 SQLite 和 Core Data。为你省下数周的时间和数千行的代码,帮你创造出更棒的用户体验。--Realm官网
优势
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("john@corporation.com");
}
});
- Write
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
////////
User user = new User("John");
user.setEmail("john@corporation.com");
// 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<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");
// Execute the query:
RealmResults<User> result1 = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<User> result2 = realm.where(User.class)
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.findAll();
// sort
RealmResults<User> 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<Dog> 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<Dog> 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 创建了 proxy 对象,同时复写了get 和set方法。
- 配合rxjava中,所有操作都在io线程组进行, Realm实例当前使用,当次获取
Realm.getDefaultInstance()
, 结束后realm.close
。 - stetho-realm 。在chrome中查看Realm数据库。