Atlas Device SDK 已弃用。 有关详细信息,请参阅弃用页面。
嵌入式对象是一种特殊类型的Realm 对象,用于对有关特定对象的复杂数据进行建模。 嵌入式对象与关系类似,但它们提供了额外的约束,并且更自然地映射到非规范化的 MongoDB document model 。
Realm 强制执行唯一的所有权约束,将每个嵌入式对象视为单个特定父对象内的嵌套数据。嵌入式对象继承其父对象的生命周期,不能作为独立的 Realm 对象存在。如果嵌入式对象的父对象被删除或被新的嵌入式对象实例覆盖,Realm 则会自动删除嵌入式对象。
嵌入式对象数据模型
您可以使用 Realm 对象模型或服务器端文档模式定义嵌入式对象类型。嵌入式对象类型带有可重用性和可组合性。您可以在多个父对象类型中使用相同的嵌入式对象类型,也可以在其他嵌入式对象内部嵌入对象。
重要
嵌入式对象无法具备主键。
Realm 对象模型
要定义嵌入式对象,请从RealmObject派生一个类,设立RealmClass注释的 embedded属性设置为true 。 您可以像定义关系一样从父对象类型引用嵌入式对象类型:
// Define an embedded object public class Address extends RealmObject { String street; String city; String country; String postalCode; public Address(String street, String city, String country, String postalCode) { this.street = street; this.city = city; this.country = country; this.postalCode = postalCode; } public Address() {} } // Define an object containing one embedded object public class Contact extends RealmObject { private ObjectId _id = new ObjectId(); String name = ""; // Embed a single object. // Embedded object properties must be marked optional Address address; public Contact(String name, Address address) { this.name = name; this.address = address; } public Contact() {} } // Define an object containing an array of embedded objects public class Business extends RealmObject { private ObjectId _id = new ObjectId(); String name = ""; // Embed an array of objects RealmList<Address> addresses = new RealmList<Address>(); public Business(String name, RealmList<Address> addresses) { this.name = name; this.addresses = addresses; } public Business() {} }
// Define an embedded object open class Address( var street: String? = null, var city: String? = null, var country: String? = null, var postalCode: String? = null ): RealmObject() {} // Define an object containing one embedded object open class Contact(_name: String = "", _address: Address? = null) : RealmObject() { var _id: ObjectId = ObjectId() var name: String = _name // Embed a single object. // Embedded object properties must be marked optional var address: Address? = _address } // Define an object containing an array of embedded objects open class Business(_name: String = "", _addresses: RealmList<Address> = RealmList()) : RealmObject() { var _id: ObjectId = ObjectId() var name: String = _name // Embed an array of objects var addresses: RealmList<Address> = _addresses }
JSON schema
嵌入式对象映射到父类型模式中的嵌入式文档。此行为与常规 Realm 对象不同,后者映射到自己的 MongoDB 集合。
{ "title": "Contact", "bsonType": "object", "required": ["_id"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "address": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } }
{ "title": "Business", "bsonType": "object", "required": ["_id", "name"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "addresses": { "bsonType": "array", "items": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } } }
读取和写入嵌入式对象
创建嵌入式对象
要创建嵌入式对象,请将嵌入式对象的实例分配给父对象的属性:
User user = app.currentUser(); String partitionValue = "My Project"; SyncConfiguration config = new SyncConfiguration.Builder(user, partitionValue) .build(); Realm realm = Realm.getInstance(config); Address address = new Address("123 Fake St.", "Springfield", "USA", "90710"); Contact contact = new Contact("Nick Riviera", address); realm.executeTransaction(transactionRealm -> { transactionRealm.insert(contact); }); realm.close();
val user: User? = app.currentUser() val partitionValue: String = "<partition>" // replace this with a partition key val config = SyncConfiguration.Builder(user!!, partitionValue) .build() val realm: Realm = Realm.getInstance(config) val address = Address("123 Fake St.", "Springfield", "USA", "90710") val contact = Contact("Nick Riviera", address) realm.executeTransaction { transactionRealm -> transactionRealm.insert(contact) } realm.close()
更新嵌入式对象属性
若要更新嵌入式对象中的属性,请在写入事务中修改该属性:
// assumes that at least one contact already exists in this partition Contact resultContact = realm.where(Contact.class).findFirst(); realm.executeTransaction(transactionRealm -> { resultContact.address.street = "Hollywood Upstairs Medical College"; resultContact.address.city = "Los Angeles"; resultContact.address.postalCode = "90210"; Log.v("EXAMPLE", "Updated contact: " + resultContact); }); realm.close();
// assumes that at least one contact already exists in this partition val result = realm.where<Contact>().findFirst()!! realm.executeTransaction { transactionRealm -> result.address?.street = "Hollywood Upstairs Medical College" result.address?.city = "Los Angeles" result.address?.postalCode = "90210" Log.v("EXAMPLE", "Updated contact: ${result.name}") } realm.close()
覆盖嵌入式对象
要覆盖嵌入式对象,请在写事务中将一方的嵌入式对象属性重新分配给新实例。
// assumes that at least one contact already exists in this partition Contact oldContact = realm.where(Contact.class).findFirst(); realm.executeTransaction(transactionRealm -> { Address newAddress = new Address( "Hollywood Upstairs Medical College", "Los Angeles", "USA" "90210" ); oldContact.address = newAddress; Log.v("EXAMPLE", "Replaced contact: " + oldContact); }); realm.close();
// assumes that at least one contact already exists in this partition val oldContact = realm.where<Contact>().findFirst()!! realm.executeTransaction { transactionRealm -> val newAddress = Address( "Hollywood Upstairs Medical College", "Los Angeles", "USA", "90210") oldContact.address = newAddress Log.v("EXAMPLE", "Updated contact: $oldContact") } realm.close()
查询嵌入式对象属性的集合
根据嵌入式对象属性值,使用点符号对对象集合进行过滤或排序:
注意
无法直接查询嵌入式对象。而是通过对父对象类型的查询来访问嵌入式对象。
RealmResults<Contact> losAngelesContacts = realm.where(Contact.class) .equalTo("address.city", "Los Angeles") .sort("address.street").findAll(); Log.v("EXAMPLE", "Los Angeles contacts: " + losAngelesContacts);
val losAngelesContacts = realm.where<Contact>() .equalTo("address.city", "Los Angeles") .sort("address.street").findAll() Log.v("EXAMPLE", "Los Angeles Contacts: $losAngelesContacts")