美文网首页JavaAndroid知识Android技术知识
Realm Java官方教程翻译(三):Relationship

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

作者: 青蛙要fly | 来源:发表于2016-12-10 23:28 被阅读486次

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

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

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

    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<T>字段声明来建立与任何数量的objects之间的关系。举例来说,一个contact会有多个email地址。

    public class Contact extends RealmObject {
        public String name;
        public RealmList<Email> 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 = "john@example.com";
            email1.active = true;
            contact.emails.add(email1);
    
            Email email2 = realm.createObject(Email.class);
            email2.address = "jd@example.com";
            email2.active = false;
            contact.emails.add(email2);
        }
    });
    

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

    public class Person extends RealmObject {
        public String name;
        public RealmList<Person> 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<Dog> dogs;
      // getters and setters
    }
    
    public class Dog extends RealmObject {
      private String id;
      private String name;
      private String color;
      // getters and setters
    }
    

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

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

    // persons => [U1,U2]
    RealmResults<Person> 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<Person> r1 = realm.where(Person.class)
                                 .equalTo("dogs.name", "Fluffy")
                                 .findAll();
    
    // r2 => [U1,U2]
    RealmResults<Person> r2 = r1.where()
                              .equalTo("dogs.color", "Brown")
                              .findAll();
    

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

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

    // r1 => [U1,U2]
    RealmResults<Person> r1 = realm.where(Person.class)
                                 .equalTo("dogs.name", "Fluffy")
                                 .equalTo("dogs.color", "Brown")
                                 .findAll();
    
    // r2 => [U2]
    RealmResults<Person> 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<Person> 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官方教程翻译(三):Relationship

      本文链接:https://www.haomeiwen.com/subject/gjujmttx.html