Relacionamentos - Kotlin SDK
Nesta página
Esta página descreve como definir relacionamentos entre objetos em seu modelo de dados. Para saber mais sobre os objetos de Realm e como defini-los, consulte Definir um Realm Object Model - Kotlin SDK.
Ao contrário de um banco de dados relacional, o Realm não usa tabelas de ponte ou junções explícitas para definir relacionamentos. Em vez disso, o Realm lida com relações por meio de objetos incorporados ou propriedades de referência a outros objetos do Realm. Você lê e grava diretamente nessas propriedades. Isso torna a query de relações tão eficiente quanto a query de qualquer outra propriedade.
Tipos de relacionamento
Existem dois tipos principais de relacionamentos entre objetos de Realm:
Relacionamento para um
Relacionamento com muitos
O Realm não limita inerentemente as referências de objeto de outros objetos dentro do mesmo Realm. Isso significa que os relacionamentos do Realm são implicitamente "muitos para um" ou "muitos para muitos". A única maneira de restringir um relacionamento a "um para um/um para muitos" em vez de "muitos para um/muitos para muitos" é usar um objeto incorporado, que é um objeto aninhado com exatamente um pai.
Definir uma relação
Você pode definir relacionamentos em seu esquema de objetos definindo uma propriedade de objeto que faça referência a outro objeto do Realm. Saiba mais sobre como usar objetos de Realm como propriedades.
Você pode definir relacionamentos usando os seguintes tipos:
RealmObject
RealmList <? extends RealmObject>
RealmSet <? extends RealmObject>
Você também pode incorporar um Objeto de Realm diretamente dentro de outro para criar uma estrutura de dados aninhada com um tipo EmbeddedRealmObject
. No entanto, os objetos embarcados têm restrições adicionais. Consulte a seção Definir um objeto embarcado para obter mais informações.
Definir uma propriedade de relacionamento um-para-um
Um relacionamento de relacionamento para um mapeia uma propriedade para uma instância única de um tipo de objeto de RealmObject
. Nada impede que várias instâncias de objeto pai façam referência à mesma instância filho. Se você deseja impor um relacionamento individual rigoroso, use um objeto incorporado .
Observação
Definir um campo de relacionamento um e um como null
remove a conexão entre os objetos, mas o Realm não exclui o objeto referenciado. Se você quiser excluir o objeto referenciado quando o objeto pai for excluído, use um objeto incorporado .
Para definir um relacionamento entre objetos, defina uma propriedade de objeto opcional cujo tipo seja um objeto RealmObject
definido em seu modelo de dados. Pode ser um tipo de objeto de Realm diferente ou o mesmo tipo de objeto de Realm:
// Relationships of Realm objects must be of RealmObject type class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int = 0 // Property of RealmObject type (MUST be null) var favoritePond: Pond? = null var bestFriend: Frog? = null }
Definir uma propriedade de relacionamento um-para-muitos
Um relacionamento para muitos mapeia uma propriedade para zero ou mais instâncias de um tipo de objeto RealmObject
. Nada impede que várias instâncias de objetos pai façam referência à mesma instância filho. Se você quiser impor um relacionamento rigoroso de um para muitos, use um objeto incorporado.
No Realm, relacionamentos para muitos são coleções (a RealmList ou RealmSet) de Objetos de Realm . Para obter mais informações sobre como definir coleções em seu modelo de objetos, consulte Definir propriedades de coleções.
Para definir uma relacionamento para muitos entre objetos, defina uma propriedade de objeto cujo tipo seja RealmList<E>
ou RealmSet<E>
, onde <E>
é um tipo de objeto RealmObject
definido em seu modelo de dados. Pode ser um Tipo de objeto de Realm diferente ou o mesmo Tipo de objeto de Realm:
// Relationships of RealmList<E> or RealmSet<E> must be of RealmObject type class Forest : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Set of RealmObject type (CANNOT be null) var frogsThatLiveHere: RealmSet<Frog> = realmSetOf() // List of RealmObject type (CANNOT be null) var nearbyPonds: RealmList<Pond> = realmListOf() }
Definir um relacionamento inverso
Um relacionamento inverso é um relacionamento automático de backlink entre um objeto RealmObject
filho e quaisquer outros objetos pai que se refiram a ele. Relações inversas podem se linkar de volta a objetos filhos em uma relação muitos-para-um ou muitos-para-muitos. Se você quiser impor um relacionamento inverso rigoroso de um para um ou de um para muitos, use um objeto incorporado.
As definições de relacionamento são unidirecionais, então você deve definir explicitamente uma propriedade no modelo do objeto como um relacionamento inverso. Por exemplo, o relacionamento "O usuário tem muitas publicações" não cria automaticamente o relacionamento inverso "A publicação pertence ao usuário". Mas você pode adicionar uma propriedade de usuário na postagem que aponte de volta para o proprietário da postagem. Isso permite que você consulte a relacionamento inversa da postagem para o usuário, em vez de executar uma query separada para procurar o usuário ao qual a postagem pertence. Como os relacionamentos são muitos para um ou muitos para muitos, seguir relacionamentos inversos pode resultar em zero, um ou muitos objetos.
Observação
O Realm atualiza automaticamente relacionamentos implícitos sempre que um objeto é adicionado ou removido do relacionamento especificado. Você não pode adicionar ou remover itens manualmente de uma coleção de backlinks.
Para definir uma relação inversa entre objetos, primeiro defina uma propriedade de coleção no objeto pai cujo tipo é RealmList<E>
, RealmSet<E>
ou RealmDictionary<E>
, onde <E>
é um tipo de objeto RealmObject
definido em seu modelo de dados . Pode ser um tipo de objeto de Realm diferente ou o mesmo tipo de objeto de Realm:
// Parent object must have RealmList<E>, RealmSet<E>, or // RealmDictionary<K,V> property of child type class User : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of child RealmObject type (CANNOT be nullable) var posts: RealmList<Post> = realmListOf() // Set of child RealmObject type (CANNOT be nullable) var favoritePosts: RealmSet<Post> = realmSetOf() // Dictionary of child RealmObject type (value MUST be nullable) var postByYear: RealmDictionary<Post?> = realmDictionaryOf() }
Em seguida, defina uma propriedade de backlinks imutável no objeto filho de RealmResults<E>
, onde <E>
é o tipo de objeto pai:
// Backlink of RealmObject must be RealmResults<E> of parent object type class Post : RealmObject { var title: String = "" var date: RealmInstant = RealmInstant.now() // Backlink to parent RealmObject type (CANNOT be null & MUST be val) val user: RealmResults<User> by backlinks(User::posts) }
Definir um Objeto Embarcado
Um objeto incorporado é um tipo especial de Objeto de Realm que você pode usar para aninhar dados dentro de um único objeto pai específico. Os objetos incorporados podem estar em um relacionamento um-para-um, um-para-muitos ou inverso semelhante aos relacionamento descritos nas seções anteriores, exceto que o relacionamento é restrito a um relacionamento -um-para-um-para-um único objeto pai e um EmbeddedRealmObject
tipo .
Como os objetos embarcados não podem existir como objetos de Realm independentes, eles têm restrições adicionais a serem consideradas:
Um objeto incorporado tem propriedade estrita de seu pai. Você não pode compartilhar objetos embarcados entre objetos pai.
O objeto incorporado herda o ciclo de vida de seu principal. Por exemplo, excluir o objeto principal também exclui o objeto incorporado.
Objetos embarcados são úteis quando há um relacionamento claro de contenção ou propriedade. Por exemplo, um objeto Address
pode ser incorporado em um objeto User
porque só é significativo em seu aplicação dentro do contexto de um usuário.
Dica
Os tipos de objetos incorporados são reutilizáveis e componíveis
Você pode usar o mesmo tipo de objeto incorporado em vários tipos de objeto pai e dentro de outros tipos de objeto incorporado .
Relacionamento individual
Para definir um objeto embarcado com um relacionamento um-para-um com seu pai, defina uma propriedade de objeto cujo tipo seja um EmbeddedRealmObject
já definido em seu modelo de dados:
// To-one embedded relationships must be of EmbeddedRealmObject type class Contact : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Property of EmbeddedRealmObject type (MUST be null) var address: EmbeddedAddress? = null } class EmbeddedAddress : EmbeddedRealmObject { var propertyOwner: Contact? = null var street: String? = "" // Embed another EmbeddedRealmObject type var country: EmbeddedCountry? = null } class EmbeddedCountry : EmbeddedRealmObject { var name: String = "" }
Relacionamento de um para muitos
Para definir um objeto embarcado com uma relação embarcada de um para muitos com seu pai, defina uma propriedade de objeto cujo tipo seja RealmList<E>
, em que <E>
é um tipo de objeto EmbeddedRealmObject
definido em seu modelo de dados:
// To-many embedded relationships must be a RealmList<E> or // RealmDictionary<K, V> property of EmbeddedRealmObject type class Business : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of EmbeddedRealmObject type (CANNOT be null) var addresses: RealmList<EmbeddedAddress> = realmListOf() // Dictionary of EmbeddedRealmObject type (value MUST be nullable) var addressByYear: RealmDictionary<EmbeddedAddress?> = realmDictionaryOf() }
Você não pode definir um objeto embarcado com um tipo RealmSet<E>
, pois RealmSet<E>
não suporta objetos embarcados.
Relacionamento inverso
Para definir um objeto incorporado com uma relação inversa com seu pai, primeiro defina uma propriedade de coleção no objeto principal cujo tipo é RealmList<E>
ou RealmDictionary<E>
, onde <E>
é um tipo de objeto EmbeddedRealmObject
definido em seu modelo de dados :
// Parent object must have RealmList<E> or RealmDictionary<K, V> // property of child EmbeddedRealmObject type class User : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of child EmbeddedRealmObject type (CANNOT be nullable) var posts: RealmList<Post> = realmListOf() // Dictionary of child EmbeddedRealmObject type (value MUST be nullable) var postByYear: RealmDictionary<Post?> = realmDictionaryOf() }
Você não pode definir um objeto embarcado com um tipo RealmSet<E>
, pois RealmSet<E>
não suporta objetos embarcados.
Em seguida, defina uma propriedade de backlinks imutável no objeto filho cujo tipo é o tipo de objeto pai:
// Backlink of EmbeddedRealmObject must be parent object type class Post : EmbeddedRealmObject { var title: String = "" var date: RealmInstant = RealmInstant.now() // Backlink to parent RealmObject type (CANNOT be null & MUST be val) val user: User by backlinks(User::posts) }