今天我们翻译下图显示的目录中的Getting Help模块及Models模块。
学习步骤
这篇翻译所要翻译的内容如下图所示:
本篇学习内容
Getting Help
对于你的代码是否需要帮忙?在StackOverflow : realm上进行询问,我们会积极的查看问题及进行回答!
是否有bug需要提交给我们?Open an issue on our repo,如果可以,提交信息里面包含Realm的版本,完整的log,Realm的文件和产生改问题的项目。
是否有功能要求?Open an issue on our repo,告诉我们这个功能应该怎么实现什么及你为什么想要该功能。
Love to follow what comes up next? Look at our changelog. 日志里面会显示我们计划最近释放版本所添加的内容及变化。及Realm逐步发展的历史。
Models
Realm的model类是通过继承RealmObject 基础类来创建的。
代码语言:javascript复制public class User extends RealmObject {
private String name;
private int age;
@Ignore
private int sessionId;
//通过你的IDE来生成标准的getters和setters方法
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; }
}
一个Realm 的model类不但支持private,protected和private的字段,而且还支持自定义方法。
代码语言:javascript复制public class User extends RealmObject {
public String name;
public boolean hasLongName() {
return name.length() > 7;
}
@Override
public boolean equals(Object o) {
// Custom equals comparison
}
}
字段类型
Realm支持下面所示的字段类型:
- boolean
- byte
- short
- int
- long
- float
- double
- String
- Date
- byte[]
整数类型byte
, short
, int
和 long
在Realm中都是映射到同一类型(实际上是long
)。
此外,在model relationships中支持RealmObject的子类和RealmList。
封装类型Boolean
, Byte
, Short
,Integer
, Long
, Float
, Double
也能在model类中被使用。在使用这种封装类型的时候。它的值有可能是null。
Required fields and null values
在一些情况下,用null来作为字段的值来说并不合适。所以@Required注解可以使Realm进行强制检查,从而不允许为null值。只有 Boolean
, Byte
, Short
, Integer
, Long
, Float
,Double
, String
,
byte[]
和 Date
类型能用@Required来注解。基本数据类型和RealmList类型是隐性的使用了。RealmObject类型经常是可允许为null。
Ignoring properties
@Ignore注解意味着字段不需要被持久化到磁盘中。如果你要输入比你的model更多的字段,并且你又不希望在很多特殊情况来处理这些未使用的数据字段。这时候Ignored字段就起到作用了,
Auto-Updating Objects
RealmObject 灵活并自动化更新底层数据视图。这意味着objects并没有被刷新,当修改那些作用于查询中的objects时,将会迅速的反映到结果中来。
代码语言:javascript复制realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Dog myDog = realm.createObject(Dog.class);
myDog.setName("Fido");
myDog.setAge(1);
}
});
Dog myDog = realm.where(Dog.class).equalTo("age", 1).findFirst();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Dog myPuppy = realm.where(Dog.class).equalTo("age", 1).findFirst();
myPuppy.setAge(2);
}
});
myDog.getAge(); // => 2
所有的RealmObject ’s和RealmResults的这一属性,不但能让Realm快速及有效,而且还让你的代码更加的简便和灵活。举个例子,如果你的Activity和Fragment依赖于某个特定的RealmObject或者RealmResults实例,这时候不需要担心在更新UI前要先去刷新和重新获取实例。
你能对 Realm notifications 进行订阅。这样当Realm的数据被更新的时候,就可以指示你app的UI进行更新操作。
Indexing properties
@Index注解将会对字段添加一个搜索的索引。这样会使插入数据变慢,然后data文件也会更大,但是查询起来会变的更快。所以推荐在对特定情况下的读取性能上优化时,才添加索引。
我们索引支持:String
,byte
, short
, int
, long
, boolean
和 Date
字段。
Primary keys
将一个字段设置为主键,你需要使用@PrimaryKey注解,字段的类型要么是string(String),要么就是integer(byte,short,int或者long)和它的封装体(Byte,Short,Integer,和Long)。
不能使用多个字段(复合键)来作为主键。 使用string的字段作为主键,则该字段隐式的被进行了索引注解。(@PrimaryKey注解 设置了 @Index注解)
使用主键后能够使用copyToRealmOrUpdate()
方法,该方法可以找到含有该主键的所存在的object,如果找到则进行更新;如果没有找到则创建一个新的Object。当对classes进行调用copyToRealmOrUpdate()
方法的时候,如果classes没有主键,则会抛出异常。
使用主键会影响性能。创建和更新object会变慢,但是查询会变快。很难给出一个值来说明性能上的变化,因为这还依赖你的数据集的大小。
当调用Realm.createObject(),它将返回一个新的object,这个object里面的所有字段都是设为默认值。但在这种情况下,有可能会跟已经存在的并且主键字段的值也是默认值的object发生冲突。为了避免这种情况,所以先创建一个未托管的object。然后设置字段的值,再将其通过copyToRealm()
方法拷贝到Realm中。
final MyObject obj = new MyObject();
obj.setId(42);
obj.setName("Fish");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
//realm.copyToRealm(obj)这个方法将会在Realm中创建一个新的object
//或者是抛出一个异常(Realm中已经存在一个具有相同主键值为42的object)
// realm.copyToRealm(obj);
//创建一个新的object,
//或者是更新object (Realm中存在且觉有相同的主键值为42的object)
realm.copyToRealmOrUpdate(obj);
}
});
对于String (String) 和封装的integer (Byte, Short, Integer, 和 Long),主键的值可以为null。除非@PrimaryKeyz注解和@Required注解一起使用,这时候就不能为null。
Customizing Objects
使用RealmObject
s和POJOs用法很像。继承RealmObject,你能让字段为public,能通过简单的书写方式来替代setters和getters方法。
下面是一个model class的例子:
public class Dog extends RealmObject {
public String name;
public int age;
}
你能想使用其他class一样来使用Dog这个类。为了在Realm中创建一个托管类Dog,你能使用createObject() 或者 copyToRealm()方法。
代码语言:javascript复制realm.executeTransaction(new Realm.Transaction() {
@Overrride
public void execute(Realm realm) {
Dog dog = realm.createObject(Dog.class);
dog.name = "Fido";
dog.age = 5;
}
};
如果可以更好的符合你的需求,你可以在你的setters和getters方法里面添加逻辑。如果你想在存储之前来验证值的时候,就这会变的有用。此外,你能方便的在你的RealmObject中添加自定义方法。
Limitations
当前并不支持final ,trasient和volatile的字段。这主要是为了避免一个object在Realm中被托管及不被托管的表现的差异。 Realm 的 model classes 不允许去继承其他类除了RealmObject。 如果声明,则默认的构造器(无参构造器)一定要是空的。原因是 一个默认的构造器将会调用那些假定Realm实例存在的方法,但是在构造函数返回前实例并没有被创建 。为了你的方便使用,你可以添加其他的构造器。
RealmModel interface 除了继承RealmObject这个基本类,我们还可以通过实现RealmModel 接口及添加@RealmClass注解的方式来替换。
代码语言:javascript复制@RealmClass
public class User implements RealmModel {
}
那些在RealmObject中能使用的方法,也能通过静态方法来使用。
代码语言:javascript复制// With RealmObject
user.isValid();
user.addChangeListener(listener);
// With RealmModel
RealmObject.isValid(user);
RealmObject.addChangeListener(user, listener);