Realm Java 官方教程翻译 (二):Getting Help 及 Models

2024-01-27 11:31:06 浏览数 (2)

今天我们翻译下图显示的目录中的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 , intlong 在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文件也会更大,但是查询起来会变的更快。所以推荐在对特定情况下的读取性能上优化时,才添加索引。 我们索引支持:Stringbyte, short, int, long, booleanDate字段。

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中。

代码语言:javascript复制
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 使用RealmObjects和POJOs用法很像。继承RealmObject,你能让字段为public,能通过简单的书写方式来替代setters和getters方法。 下面是一个model class的例子:

代码语言:javascript复制
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);

0 人点赞