上幾篇鏈接:
Realm Java官方教程翻譯(一):Getting Started
Realm Java官方教程翻譯(二):Getting Help及Models
今天我們翻譯下圖顯示的目錄中的Relationships模塊。
這篇翻譯所要翻譯的內(nèi)容如下圖所示:
Relationships
任意二個(gè)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 方法
}
**這一段大概意思懂藕咏,但不知道該怎么直譯比較好耻姥,一些專業(yè)的在數(shù)據(jù)庫(kù)中的術(shù)語(yǔ)不好直接翻譯。請(qǐng)大家?guī)兔聪隆O旅嬖u(píng)論里回復(fù)下来农。謝謝了
(我是這么翻譯的:在Realm中,Relationships 在Realm中是低消耗的崇堰。這意味著沃于,建立一個(gè)鏈接在速度方面并不是高消耗,并且relationships的內(nèi)部展現(xiàn)在內(nèi)存消耗方面又是高效的海诲。)
**
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子類中定義一個(gè)屬性繁莹,
public class Contact extends RealmObject {
private Email email;
// Other fields…
}
每個(gè)contact (Contact
實(shí)例) 有 0個(gè)或者1個(gè) email (Email
實(shí)例)。在Realm中特幔,無(wú)法阻止你在不同的contact對(duì)象中使用相同的email對(duì)象咨演。并且上述的model可以是many-to-one(多對(duì)一)的關(guān)系。但是經(jīng)常被用做成為one-to-one(一對(duì)一)的關(guān)系蚯斯。
設(shè)置RealmObject
為 null
薄风,將會(huì)清除引用但是object不會(huì)從Realm中刪除饵较。
Many-to-Many
通過(guò)object中的 RealmList<T>
字段聲明來(lái)建立與任何數(shù)量的objects之間的關(guān)系。舉例來(lái)說(shuō)遭赂,一個(gè)contact會(huì)有多個(gè)email地址循诉。
public class Contact extends RealmObject {
public String name;
public RealmList<Email> emails;
}
public class Email extends RealmObject {
public String address;
public boolean active;
}
RealmList
s 主要包含RealmObject
s骂蓖,并且RealmList
表現(xiàn)的很像Java的List
舔腾。在Realm中蛛壳,對(duì)于一個(gè)相同的object 在不同的RealmList
s中被使用了二次(或者更多)并不進(jìn)行限制廊移。因此你能對(duì)model使用one-to-many(一對(duì)多)和many-to-many(多對(duì)多)關(guān)系剩晴。
你能創(chuàng)建objects ,并且使用RealmList.add()
來(lái)給Contact
對(duì)象添加Email
對(duì)象深碱。
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);
}
});
當(dāng)在給確定的數(shù)據(jù)類型建立模型的時(shí)候草讶,進(jìn)行聲明遞歸關(guān)系會(huì)顯得有用昔园。
public class Person extends RealmObject {
public String name;
public RealmList<Person> friends;
// Other fields…
}
將RealmList
字段的值設(shè)置為null
后會(huì)清空l(shuí)ist僻弹。就是說(shuō)list將會(huì)變空(長(zhǎng)度為0)阿浓,但是沒(méi)有objects被刪除,RealmList
的getter方法獲取永遠(yuǎn)不會(huì)為null
蹋绽。返回的objects總是為list芭毙,但是長(zhǎng)度可能是0。
Link queries
有可能需要查詢鏈接或關(guān)系卸耘,細(xì)想下面的這個(gè)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
}
如這個(gè)圖所示:每個(gè)Person
對(duì)象會(huì)有多個(gè)dog的關(guān)系退敦。
讓我們來(lái)通過(guò)鏈接查詢找到一些person。
// persons => [U1,U2]
RealmResults<Person> persons = realm.where(Person.class)
.equalTo("dogs.color", "Brown")
.findAll();
首先蚣抗,注意到equalTo
里面的字段包含了關(guān)系對(duì)應(yīng)的方式(通過(guò).
分割)侈百。
上面的查詢可以這么理解:查詢出所有的人,而且這些人都有著顏色為“Brown”的狗翰铡。重要的是要懂的:這些搜出來(lái)的Person object中也會(huì)包含那些不滿足條件的Dog
objects钝域。因?yàn)檫@些不滿足的Dog objects 也是Person
’s object的一部分。
persons.get(0).getDogs(); // => [A,B]
persons.get(1).getDogs(); // => [B,C,D]
這可以通過(guò)以下兩個(gè)查詢進(jìn)一步檢查锭魔。
// 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();
注意到第一個(gè)查詢返回了二個(gè)Person objects ,因?yàn)檫@二個(gè)persons 符合條件例证,查詢到的結(jié)果中每個(gè)Person都包含著一系列的Dog objects(是他們所擁有的所有的狗,即使有些狗不滿足查詢時(shí)候的條件)迷捧。記住织咧,我們搜索的是擁有特定種類的狗(狗的名字和狗的顏色)的那些人。而不是去搜這些特定的狗漠秋。因此笙蒙,第二個(gè)查詢也將與第一個(gè)查詢的Person(r1)及這些Person的dogs也一樣。這些人也都符合第二次查詢的條件庆锦,只是這次是通過(guò)狗的顏色來(lái)查詢的捅位。
讓我們?cè)偕钊胍稽c(diǎn)了解情況,幫助鞏固這個(gè)概念。請(qǐng)看下面的例子:
// 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();
第一個(gè)查詢可以這么理解:分別查找擁有名叫Fluffy小狗的所有Persons及查找擁有小狗顏色為Brown的所有Persons。然后對(duì)二者所查到的Persons取交集绿渣。
第二個(gè)查詢可以這么理解:查找擁有名字叫Fluffy小狗的所有Persons朝群。然后在該結(jié)果集中繼續(xù)查找擁有顏色為“Brown”小狗的所有Persons,然后再在該結(jié)果集中繼續(xù)查找擁有顏色為“Yellow”的所有Persons。
讓我們?cè)敿?xì)了解下 r1
這個(gè)結(jié)果的背后到底發(fā)生了什么中符。二個(gè)條件分別是equalTo("dogs.name", "Fluffy")
和 equalTo("dogs.color", "Brown")
姜胖。滿足第一個(gè)條件的是U1和U2(記這個(gè)結(jié)果集為C1)。滿足第二個(gè)條件的是U1和U2(記這個(gè)結(jié)果集為C2)淀散。在查詢中的‘與’邏輯操作相當(dāng)于對(duì)C1和C2的交集右莱。而C1和C2的交集就是U1和U2,所以r1就是U1和U2.
第二個(gè)查詢的結(jié)果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 的結(jié)果集中只有一個(gè)person有 Yesllow dog,即U2晨抡。