Realm Java官方教程翻译(三):Relationships


上几篇链接:
Realm Java官方教程翻译(一):Getting Started
Realm Java官方教程翻译(二):Getting Help及Models


今天我们翻译下图显示的目录中的Relationships模块

Realm Java官方教程翻译(三):Relationships_第1张图片

这篇翻译所要翻译的内容如下图所示:

Relationships

任意二个RealmObjects 能够被连接到一起。

public class Email extends RealmObject {
    private String address;
    private boolean active;
    // ... setters 和 getters方法
}

public class Contact extends RealmObject {
    private String name;
    private Email email;
    // ... setters 和 getters 方法
}

**这一段大概意思懂,但不知道该怎么直译比较好,一些专业的在数据库中的术语不好直接翻译。请大家帮忙看下。下面评论里回复下。谢谢了
(我是这么翻译的:在Realm中,Relationships 在Realm中是低消耗的。这意味着,建立一个链接在速度方面并不是高消耗,并且relationships的内部展现在内存消耗方面又是高效的。)
**

Relationships are generally cheap in Realm. This means that following a link is not expensive in terms of speed, and the internal presentation of relationships is highly efficient in terms of memory consumption.


Many-to-One

在你的类型为RealmObject子类中定义一个属性,

public class Contact extends RealmObject {
    private Email email;
    // Other fields…
}

每个contact (Contact实例) 有 0个或者1个 email (Email实例)。在Realm中,无法阻止你在不同的contact对象中使用相同的email对象。并且上述的model可以是many-to-one(多对一)的关系。但是经常被用做成为one-to-one(一对一)的关系。

设置RealmObjectnull,将会清除引用但是object不会从Realm中删除。

Many-to-Many

通过object中的 RealmList字段声明来建立与任何数量的objects之间的关系。举例来说,一个contact会有多个email地址。

public class Contact extends RealmObject {
    public String name;
    public RealmList emails;
}

public class Email extends RealmObject {
    public String address;
    public boolean active;
}

RealmLists 主要包含RealmObjects,并且RealmList表现的很像Java的List。在Realm中,对于一个相同的object 在不同的RealmLists中被使用了二次(或者更多)并不进行限制。因此你能对model使用one-to-many(一对多)和many-to-many(多对多)关系。

你能创建objects ,并且使用RealmList.add()来给Contact 对象添加Email 对象。

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        Contact contact = realm.createObject(Contact.class);
        contact.name = "John Doe";

        Email email1 = realm.createObject(Email.class);
        email1.address = "[email protected]";
        email1.active = true;
        contact.emails.add(email1);

        Email email2 = realm.createObject(Email.class);
        email2.address = "[email protected]";
        email2.active = false;
        contact.emails.add(email2);
    }
});

当在给确定的数据类型建立模型的时候,进行声明递归关系会显得有用。

public class Person extends RealmObject {
    public String name;
    public RealmList friends;
    // Other fields…
}

RealmList字段的值设置为null后会清空list。就是说list将会变空(长度为0),但是没有objects被删除,RealmList的getter方法获取永远不会为null。返回的objects总是为list,但是长度可能是0。

Link queries

有可能需要查询链接或关系,细想下面的这个model:

public class Person extends RealmObject {
  private String id;
  private String name;
  private RealmList dogs;
  // getters and setters
}

public class Dog extends RealmObject {
  private String id;
  private String name;
  private String color;
  // getters and setters
}

如这个图所示:每个Person对象会有多个dog的关系。

Realm Java官方教程翻译(三):Relationships_第2张图片

让我们来通过链接查询找到一些person。

// persons => [U1,U2]
RealmResults persons = realm.where(Person.class)
                                .equalTo("dogs.color", "Brown")
                                .findAll();

首先,注意到equalTo里面的字段包含了关系对应的方式(通过.分割)。

上面的查询可以这么理解:查询出所有的人,而且这些人都有着颜色为“Brown”的狗。重要的是要懂的:这些搜出来的Person object中也会包含那些不满足条件的Dog objects。因为这些不满足的Dog objects 也是Person’s object的一部分。

persons.get(0).getDogs(); // => [A,B]
persons.get(1).getDogs(); // => [B,C,D]

这可以通过以下两个查询进一步检查。

// r1 => [U1,U2]
RealmResults r1 = realm.where(Person.class)
                             .equalTo("dogs.name", "Fluffy")
                             .findAll();

// r2 => [U1,U2]
RealmResults r2 = r1.where()
                          .equalTo("dogs.color", "Brown")
                          .findAll();

注意到第一个查询返回了二个Person objects ,因为这二个persons 符合条件,查询到的结果中每个Person都包含着一系列的Dog objects(是他们所拥有的所有的狗,即使有些狗不满足查询时候的条件)。记住,我们搜索的是拥有特定种类的狗(狗的名字和狗的颜色)的那些人。而不是去搜这些特定的狗。因此,第二个查询也将与第一个查询的Person(r1)及这些Person的dogs也一样。这些人也都符合第二次查询的条件,只是这次是通过狗的颜色来查询的。

让我们再深入一点了解情况,帮助巩固这个概念。请看下面的例子:

// r1 => [U1,U2]
RealmResults r1 = realm.where(Person.class)
                             .equalTo("dogs.name", "Fluffy")
                             .equalTo("dogs.color", "Brown")
                             .findAll();

// r2 => [U2]
RealmResults r2 = realm.where(Person.class)
                             .equalTo("dogs.name", "Fluffy")
                             .findAll()
                             .where()
                             .equalTo("dogs.color", "Brown")
                             .findAll();
                             .where()
                             .equalTo("dogs.color", "Yellow")
                             .findAll();

第一个查询可以这么理解:分别查找拥有名叫Fluffy小狗的所有Persons及查找拥有小狗颜色为Brown的所有Persons。然后对二者所查到的Persons取交集。
第二个查询可以这么理解:查找拥有名字叫Fluffy小狗的所有Persons。然后在该结果集中继续查找拥有颜色为“Brown”小狗的所有Persons,然后再在该结果集中继续查找拥有颜色为“Yellow”的所有Persons。

让我们详细了解下 r1这个结果的背后到底发生了什么。二个条件分别是equalTo("dogs.name", "Fluffy")equalTo("dogs.color", "Brown")。满足第一个条件的是U1和U2(记这个结果集为C1)。满足第二个条件的是U1和U2(记这个结果集为C2)。在查询中的‘与’逻辑操作相当于对C1和C2的交集。而C1和C2的交集就是U1和U2,所以r1就是U1和U2.

第二个查询的结果r2是不同的。首先第一部分的查询就像是这样:ealmResults r2a = realm.where(Person.class).equalTo("dogs.name", "Fluffy").findAll();
符合的条件:U1和U2。然后r2b = r2a.where().equalTo("dogs.color", "Brown").findAll();同样符合的是U1和U2(所有的人都有brown dogs),最后的查询是r2 = r2b.where().equalTo("dogs.color", "Yellow").findAll();。符合的只有U2,由于在brown dog 的结果集中只有一个person有 Yesllow dog,即U2。

你可能感兴趣的:(Realm Java官方教程翻译(三):Relationships)