前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Realm Java 官方教程翻译 (三):Relationships

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

作者头像
青蛙要fly
发布2024-01-29 08:33:51
1240
发布2024-01-29 08:33:51
举报

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

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

Relationships

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

代码语言:javascript
复制
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子类中定义一个属性,

代码语言:javascript
复制
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地址。

代码语言:javascript
复制
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 对象。

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

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

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

代码语言:javascript
复制
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的关系。

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

代码语言:javascript
复制
// 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的一部分。

代码语言:javascript
复制
persons.get(0).getDogs(); // => [A,B]
persons.get(1).getDogs(); // => [B,C,D]

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

代码语言:javascript
复制
// 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也一样。这些人也都符合第二次查询的条件,只是这次是通过狗的颜色来查询的。

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Relationships
  • Many-to-One
  • Many-to-Many
  • Link queries
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档