Criar objetos de domínio - Kotlin SDK
Nesta página
- Transações de gravação
- Objetos Gerenciados e Não Gerenciados
- Criar um Objeto de Realm
- Criar um Objeto de Realm
- Criar um Objeto Embarcado
- Criar um objeto assimétrico
- Criar propriedades do Realm
- Criar uma propriedade RealmInstant (Carimbo de data/hora)
- Criar uma propriedade MutableRealmInt (Contador)
- Criar uma propriedade RealmAny (Misto)
- Criar propriedade da collection
- Crie um RealmList
- Criar uma propriedade RealmSet
- Criar uma propriedade de dicionário
- Crie uma propriedade de relacionamento
- Crie um relacionamento para um
- Crie um relacionamento para muitos
- Crie um relacionamento inverso
- Criar uma cópia não gerenciada de um Objeto de Realm ou collection
Esta página descreve os conceitos de transação de escrita e managed objeto em um Realm e, em seguida, explica como criar e persistir um novo objeto em um Realm local ou sincronizado usando o Kotlin SDK. Para saber mais sobre objetos de Realm e como defini-los, consulte Objetos de Realm.
Você pode criar objeto cujo Tipo de objeto de Realm esteja incluído no esquema de Realm quando você abrir o Realm. Para obter mais informações, consulte Abrir um Realm ou Abrir um Realm sincronizado.
Observação
Escreva para um domínio sincronizado
A sintaxe para gravar um novo objeto em um Realm é a mesma para um Realm local ou sincronizado. No entanto, há considerações adicionais que determinam se a operação de gravação em um Realm sincronizado é bem-sucedida. Para obter mais informações, consulte Gravar dados em um Realm sincronizado - Kotlin SDK.
Transações de gravação
O Realm lida com as operações de escrita como transações. Todas as operações de escrita devem ocorrer em uma transação. Uma transação é um conjunto de operações de leitura e escrita que o Realm trata como uma única operação indivisível: ou todas as operações são bem-sucedidas ou nenhuma das operações da transação é efetivada.
O Realm representa cada transação como uma função de chamada de resposta de chamada que contém zero ou mais operações de leitura e gravação. Para executar uma transação, você define uma chamada de resposta de resposta de transação e a passa para o método write() ou writeBlocking() do domínio. Nessa chamada de chamada de resposta, você pode acessar uma instância de MutableRealm e, em seguida, criar, ler, atualizar e excluir objetos dentro do Realm. O Realm mutável representa o estado gravável de um Arquivo de Realm. Os domínios mutáveis são fornecidos e gerenciados automaticamente pelos métodos realm.write
ou realm.writeBlocking
.
Um Realm permite apenas uma transação de escrita aberta por vez. Realm bloqueia outras escritas em outras threads até que a transação aberta no Realm mutável seja concluída. Consequentemente, não há condição de corrida ao ler valores do Realm dentro de uma transação.
Quando você termina a transação, o Realm a confirma ou a cancela:
When Realm commits a transaction, Realm writes all changes to disk. Para domínios sincronizados, o SDK classifica a alteração para sincronização com o backend.
Quando o Realm cancela uma transação de escrita ou uma operação na transação causa um erro, todas as alterações são descartadas.
Observação
Objetos congelados
Objetos retornados de um fechamento de escrita se tornam objetos congelados quando a transação de escrita é concluída. Para obter mais informações, consulte Arquitetura congelada - Kotlin SDK.
Objetos Gerenciados e Não Gerenciados
As API do Realm podem se referir a objeto como managed ou não gerenciados. Quando você cria um Objeto de Realm com o Kotlin SDK, ele é unmanaged até que seja copiado para um Realm, o que cria uma managed instance.
Objetos gerenciados são objetos de Realm que persistem em um domínio. managed objeto só podem ser acessados a partir de um Realm aberto. Eles podem ser atualizados com alterações na transação de escrita, desde que esse Realm permaneça aberto. Managed objeto estão vinculados à Instância de Realm da qual se originaram e não podem ser gravados em outro Realm.
Você pode usar APIs de Realm com objetos gerenciados. Por exemplo, objetos gerenciados podem ter relacionamentos com outros objetos e serem observados quanto a alterações. Você também pode criar uma cópia não gerenciada de um objeto gerenciado, consulte a seção Criar uma cópia não gerenciada de um objeto de Realm ou coleção nesta página.
Objeto não gerenciados são instâncias de Objeto de Realm que se comportam como objeto normais de Kotlin, mas não são persistentes em um Realm. Todos os objetos de Realm não são gerenciados até que você os copie para um domínio dentro de uma transação de escrita. Você não pode usar APIs de Realm com objetos não gerenciados ou observá-los para alterações.
Dica
Você pode verificar se um objeto é gerenciado com o método isManaged() .
Criar um Objeto de Realm
Antes de criar um novo objeto e persisti-lo no Realm, você deve Definir um novo Tipo de objeto de Realm. Em seguida, você inclui esse Tipo de objeto de Realm em seu esquema de Realm quando abrir o Realm.
Importante
Tipo de objeto de Realm devem estar em seu esquema
Você só pode gravar objeto cujo Tipo de objeto de Realm esteja incluído no esquema de Realm. Se você tentar referenciar ou gravar um objeto de um Tipo de objeto de Realm que não esteja em seu esquema, o Realm retornará um erro de validação de esquema.
Para criar um novo objeto e persisti-lo no Realm:
Abra uma transação de gravação com realm.write() ou realm.writeBlocking().
Instancie uma instância de objeto não gerenciado com o construtor de classe . Você pode usar um bloco de aplicação para configurar várias propriedades de uma só vez.
Passe a instância do objeto não gerenciado para copyToRealm() para persistir os dados do objeto no domínio. Este método retorna uma instância gerenciada ativa do objeto.
Importante
objeto assimétricos usam inserção()
Objetos assimétricos são objetos especiais somente para gravação que não persistem no Realm. Eles não usam
copyToRealm()
. Em vez disso, você passa a instância de objeto assimétrica para o método de extensãoinsert()
dentro de uma transação de gravação. Consulte a seção Criar um objeto assimétrico nesta página para obter mais informações.Trabalhe com o Objeto de Realm persistente por meio da instância retornada. O objeto ativo é acessível até que a transação de escrita seja concluída. Observe que isso não se aplica a objeto assimétricos, que são somente para gravação e não persistem no Realm.
Você também pode fazer upsert em um Realm usando critérios específicos. Para obter mais informações, consulte Upsert de um Objeto de Realm.
Criar um Objeto de Realm
Para criar uma nova instância do RealmObject
, instancie um novo objeto de um Tipo de objeto de Realm.
No exemplo a seguir, instanciamos um objeto Frog
em um bloco realm.write()
e, em seguida, passamos o objeto instanciado para copyToRealm()
para retornar uma instância managed:
// Open a write transaction realm.write { // Instantiate a new unmanaged Frog object val unmanagedFrog = Frog().apply { name = "Kermit" age = 42 owner = "Jim Henson" } assertFalse(unmanagedFrog.isManaged()) // Copy the object to realm to return a managed instance val managedFrog = copyToRealm(unmanagedFrog) assertTrue(managedFrog.isManaged()) // Work with the managed object ... }
Criar um Objeto Embarcado
Para criar uma nova instância EmbeddedRealmObject
, atribua uma instância de um Tipo de objeto de Realm incorporado à propriedade de um objeto principal. Isso pode ser em um relacionamento um-para-um, um-para-muitos ou inversa, dependendo de como você definiu o objeto incorporado dentro do Tipo de objeto de Realm pai. Para obter mais informações, consulte Definir um objeto incorporado.
Observação
Objeto incorporado devem ser criados dentro de um objeto
Um objeto incorporado requer um objeto e não pode existir como um Objeto de Realm independente.
Objeto incorporado têm propriedade estrita com seu objeto pai. After you create the embedded object, you cannot reassign it to a different parent object or share it between multiple parent objects.
No exemplo a seguir, instanciamos um novo objeto Contact
com um Address
incorporado, que contém um objeto Contact
e um objeto Country
incorporado:
realm.write { // Instantiate a parent object with one embedded address val contact = Contact().apply { name = "Kermit" address = EmbeddedAddress().apply { propertyOwner = Contact().apply { name = "Mr. Frog" } street = "123 Pond St" country = EmbeddedCountry().apply { name = "United States" } } } // Copy all objects to the realm to return managed instances copyToRealm(contact) }
Também instanciamos um novo objeto Business
com uma lista de objetos Address
incorporados, que também contêm objetos Contact
e objetos Country
incorporados:
realm.write { // Instantiate a parent object with multiple embedded addresses val localOffice = EmbeddedAddress().apply { propertyOwner = Contact().apply { name = "Michigan J. Frog" } street = "456 Lily Pad Ln" country = EmbeddedCountry().apply { name = "United States" } } val remoteOffice = EmbeddedAddress().apply { propertyOwner = Contact().apply { name = "Mr. Toad" } street = "789 Leaping Frog Ave" country = EmbeddedCountry().apply { name = "Ireland" } } val business = Business().apply { name = "Big Frog Corp." addresses = realmListOf(localOffice, remoteOffice) } // Copy all objects to the realm to return managed instances copyToRealm(business) }
Criar um objeto assimétrico
Novidade na versão 1.10.0.
Ao contrário de outros Objeto de Realm, você não usa o método copyToRealm()
para criá-lo. Isso ocorre porque objeto assimétricos são somente para gravação: eles não são persistentes no Realm. Em vez disso, você usa um método de extensão insert()
especial para inseri-lo no Realm.
Para criar uma nova instância do AsymmetricRealmObject
, instancie um novo objeto de um tipo de objeto assimétrico utilizando insert().
No exemplo a seguir, instanciamos um novo objeto WeatherSensor
e o passamos para insert()
dentro de uma transação de escrita:
// Open a write transaction realm.write { // Create a new asymmetric object val weatherSensor = WeatherSensor().apply { deviceId = "WX1278UIT" temperatureInFarenheit = 6.7F barometricPressureInHg = 29.65F windSpeedInMph = 2 } // Insert the object into the realm with the insert() extension method insert(weatherSensor) // WeatherSensor object is inserted into the realm, then synced to the // App Services backend. You CANNOT access the object locally because it's // deleted from the local realm after sync is complete. }
Uma vez inserido, o objeto assimétrico é sincronizado com o backend do App Services e com o banco de dados do Atlas vinculado. Você não pode acessar os dados gerenciados localmente, adicioná-los ou removê-los de um realm ou consultá-los. Para obter informações sobre como usar objetos assimétricos em seu aplicativo, consulte Fluxo de dados para o Atlas - Kotlin SDK.
Criar propriedades do Realm
Dependendo de como você define o seu tipo de objeto, você pode ter propriedades que são tiposespeciais específicos do Realm.
No exemplo a seguir, temos um tipo de objeto Frog
com várias propriedades do Realm:
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var birthdate: RealmInstant? = null var fliesEaten: MutableRealmInt? = null var favoriteThings: RealmList<RealmAny?> = realmListOf() }
Criar uma propriedade RealmInstant (Carimbo de data/hora)
Para criar uma nova instância de objeto com uma propriedade RealmInstant , instancie um objeto e passe um valor inicial para a propriedade RealmInstant
usando:
RealmInstant.from(): os epochSeconds e nanossegundos desde a época Unix
RealmInstant.low(): os epochSeconds e nanossegundos desde a época do Unix até agora
Para obter mais informações sobre o tipo RealmInstant
, consulte RealmInstant (Carimbo de data/hora).
No exemplo a seguir, instanciamos um novo objeto Frog
com uma propriedade birthdate
e passamos um valor inicial para RealmInstant.from()
:
realm.write { // Instantiate a new unmanaged Frog object with a RealmInstant property val frog = Frog().apply { name = "Kermit" // Set an initial value with RealmInstant.from() or RealmInstant.now() birthdate = RealmInstant.from(1_577_996_800, 0) } // Copy the object to the realm to return a managed instance copyToRealm(frog) }
Criar uma propriedade MutableRealmInt (Contador)
Para criar uma nova instância de objeto com uma propriedade MutableRealmInt , instancie um objeto e passe um valor inicial para a propriedade MutableRealmInt
usando MutableRealmInt.create(). Para mais informações sobre o tipo MutableRealmInt
, consulte MutableRealmInt (Contador).
No exemplo a seguir, instanciamos um novo objeto Frog
com uma propriedade fliesEaten
e passamos um valor inicial para MutableRealmInt.create()
:
realm.write { // Instantiate a new unmanaged Frog object with a MutableRealmInt property val frog = Frog().apply { name = "Michigan J. Frog" // Set an initial value with MutableRealmInt.create() fliesEaten = MutableRealmInt.create(200) } // Copy the object to the realm to return a managed instance copyToRealm(frog) }
Criar uma propriedade RealmAny (Misto)
Para criar uma nova instância de objeto com uma propriedade polimórfica RealmAny , instancie um objeto e passe um valor inicial de um tipo suportado para a propriedade RealmAny
usando RealmAny.create(). Para obter uma lista dos tipos de valor que o RealmAny
pode conter, consulte RealmQualquer (Misto).
No exemplo a seguir, instanciamos um novo Frog
objeto com uma favoriteThings
lista do RealmAny
tipo e passamos os valores iniciais para RealmAny.create()
:
realm.write { // Instantiate a new unmanaged Frog object with a RealmAny property val frog = Frog().apply { name = "Kermit" // Set initial values with RealmAny.create() favoriteThings = realmListOf( RealmAny.create(42), RealmAny.create("rainbows"), RealmAny.create(Frog().apply { name = "Kermit Jr." }) ) } // Copy the object to the realm to return a managed instance copyToRealm(frog) }
Após criar o objeto, você deve conhecer o tipo de valor armazenado para trabalhar com a propriedade RealmAny
. Para saber como atualizar as propriedades do RealmAny
após criar o objeto, consulte Atualizar uma propriedade RealmAny (Misto).
Criar propriedade da collection
Dependendo de como você define seu tipo de objeto, você pode ter propriedades definidas como um dos seguintes tipos de coleção compatíveis:
RealmList
RealmSet
RealmDictionary
Para obter mais informações, consulte Definir propriedade da collection.
As collection são mutáveis: você pode adicionar e remover elementos em uma collection dentro de uma transação de escrita.
A collection pode conter objeto managed e não managed. Ao copiar uma collection para o Realm, você cria uma instância managed da collection e de todos os elementos da collection, inclusive quaisquer elementos não gerenciados. As coleções não gerenciadas se comportam como suas classes Kotlin correspondentes e não são persistentes no domínio.
Dica
Ouça as alterações em uma collection criada
Depois de criar uma collection, você pode registrar um manipulador de notificações para ouvir as alterações. Para obter mais informações, consulte Registrar um ouvinte de alteração de collection.
Crie um RealmList
Para criar uma nova instância de objeto com uma propriedade RealmList , instancie um objeto e passe quaisquer valores de um tipo suportado para a propriedade RealmList
. Para obter uma lista dos tipos de valor que o RealmList
pode conter, consulte RealmList.
Você pode instanciar uma lista não gerenciada com realmListOf() ou passar elementos para a lista usando list.add(), list.addAll() ou list.set(). A lista não é gerenciada até que você a copie para o Realm.
No exemplo a seguir, instanciamos um novo objeto Frog
com valores iniciais para várias propriedades RealmList
:
realm.write { // Instantiate a new unmanaged Frog object with a RealmList property val frog = Frog().apply { name = "Kermit" // Set values for each unmanaged list favoritePonds.addAll(realmListOf( Pond().apply { name = "Picnic Pond" }, Pond().apply { name = "Big Pond" } )) favoriteForests.add(EmbeddedForest().apply { name = "Hundred Acre Wood" }) favoriteWeather = realmListOf("rain", "snow") } // Copy all objects to the realm to return managed instances copyToRealm(frog) }
Criar uma propriedade RealmSet
Para criar uma nova instância de objeto com uma propriedade RealmSet , instancie um objeto e passe quaisquer valores de um tipo compatível para a propriedade RealmSet
. Para uma lista de tipos válidos que o RealmSet
pode conter, consulte RealmSet.
Você pode instanciar um conjunto não gerenciado com realmSetOf() ou passar elementos para o conjunto usando set.add() ou set.addAll(). O conjunto não será gerenciado até que você o copie para o Realm.
No exemplo a seguir, instanciamos um novo objeto Frog
com valores iniciais para favoriteSnacks
e propriedades do conjunto favoriteWeather
:
realm.write { // Instantiate a new unmanaged Frog object with RealmSet properties val frog = Frog().apply { name = "Kermit" // Set initial values to each unmanaged set favoriteSnacks.addAll(setOf( Snack().apply { name = "flies" }, Snack().apply { name = "crickets" }, Snack().apply { name = "worms" } )) favoriteWeather.add("rain") } // Copy all objects to the realm to return managed instances copyToRealm(frog) }
Criar uma propriedade de dicionário
Para criar uma nova instância de objeto com uma propriedade RealmDictionary , instancie um objeto e passe quaisquer pares de chave-valor de um tipo suportado para a propriedade RealmDictionary
. RealmDictionary
só aceita uma chave String
, mas os valores podem ser tipos não string. Para uma lista de tipos válidos, consulte RealmMap/RealmDictionary.
Você pode instanciar um dicionário não gerenciado com realmDictionaryOf() ou realmDictionaryEntryOf(). Ou você pode passar valores-chave usando put() ou putAll(). O dicionário não será gerenciado até que você o copie para o Realm.
No exemplo a seguir, instanciamos um novo objeto Frog
com valores-chave iniciais para várias propriedades do dicionário:
realm.write { val frog = Frog().apply { name = "Kermit" // Set initial key-values to each unmanaged dictionary favoriteFriendsByPond = realmDictionaryOf( "Picnic Pond" to Frog().apply { name = "Froggy Jay" }, "Big Pond" to Frog().apply { name = "Mr. Toad" } ) favoriteTreesInForest["Maple"] = EmbeddedForest().apply { name = "Hundred Acre Wood" } favoritePondsByForest.putAll( mapOf( "Silver Pond" to "Big Forest", "Big Lake" to "Elm Wood", "Trout Pond" to "Sunny Wood" ) ) } // Copy all objects to the realm to return managed instances copyToRealm(frog) }
O Realm não permite o uso de .
ou $
caracteres em chaves de mapa. Você pode usar a codificação e a decodificação percentual para armazenar uma chave de mapa que contenha um desses caracteres não permitidos.
// Percent encode . or $ characters to use them in map keys val mapKey = "Hundred Acre Wood.Northeast" val encodedMapKey = "Hundred Acre Wood%2ENortheast"
Crie uma propriedade de relacionamento
Dependendo de como você define seu Tipo de objeto de Realm, você pode ter propriedade que referenciam outro Objeto de Realm. Pode ser uma relação para-um, para-muitos ou inversa. Para obter mais informações sobre como definir relacionamentos em seu modelo de objetos, consulte Definir um relacionamento.
Você também pode incorporar um objeto de Realm diretamente dentro de outro para criar uma estrutura de dados aninhada com um tipo EmbeddedRealmObject
. Para criar um relacionamento com um objeto incorporado, consulte a seção Criar um objeto incorporado nesta página.
Crie um relacionamento para um
Para criar uma nova instância de objeto com uma propriedade de relacionamento entre si, instancie ambos os objetos e passe o objeto referenciado para a propriedade de relacionamento.
No exemplo a seguir, instanciamos um novo objeto Frog
com uma propriedade favoritePond
que referencia um objeto Pond
e uma propriedade bestFriend
que referencia outro objeto Frog
:
realm.write { // Instantiate a new unmanaged Frog object with to-one // relationship with a Realm object val frog = Frog().apply { name = "Kermit" age = 12 favoritePond = Pond().apply { name = "Picnic Pond" } bestFriend = Frog().apply { name = "Froggy Jay" } } // Copy all objects to the realm to return managed instances copyToRealm(frog) }
Crie um relacionamento para muitos
Para criar uma nova instância de objeto com uma propriedade de relacionamento para muitos , instancie todos os objeto e passe quaisquer objeto referenciados para a propriedade de collection de relacionamento.
No exemplo seguinte, instanciamos um novo objeto Forest
com uma propriedade frogsThatLiveHere
que referencia um conjunto de objetos Frog
e uma propriedade nearByPonds
que referencia uma lista de objetos Pond
:
realm.write { // Instantiate a new unmanaged Forest object with to-many // relationship with multiple Realm objects val forest = Forest().apply { name = "Froggy Forest" frogsThatLiveHere = realmSetOf( Frog().apply { name = "Kermit" }, Frog().apply { name = "Froggy Jay" } ) nearbyPonds = realmListOf( Pond().apply { name = "Small Picnic Pond" }, Pond().apply { name = "Big Pond" } ) } // Copy all objects to the realm to return managed instances copyToRealm(forest) }
Crie um relacionamento inverso
Para criar uma nova instância de objeto com uma propriedade de relacionamento inversa, instancie o objeto pai e passe qualquer objeto filho referenciado para a propriedade de collection de backlink.
No exemplo a seguir, instanciamos um novo objeto User
com uma propriedade backlink posts
que faz referência a uma lista de objeto Post
:
realm.write { // Instantiate a new unmanaged User object with to-many // relationship with multiple Realm objects val post1 = Post().apply { title = "Forest Life" } val post2 = Post().apply { title = "Top Ponds of the Year!" } val user = User().apply { name = "Kermit" posts = realmListOf(post1, post2) } // Copy all objects to the realm to return managed instances copyToRealm(user) }
After you create the object, you can access the backlinks collection property to get the child objects, but you cannot directly modify the backlink itself. Para obter mais informações, consulte Atualizar um relacionamento inverso.
Criar uma cópia não gerenciada de um Objeto de Realm ou collection
Você pode criar uma cópia não gerenciada de um objeto gerenciado ou coleção passando para copyFromRealm(). Este método retorna uma cópia não gerenciada na memória do objeto ou coleção. Para collections, esta é uma cópia profunda que inclui todos os objetos referenciados até o depth
especificado.
No exemplo a seguir, criamos uma cópia não managed de um objeto Pond
managed existente que contém uma lista de dois objeto Frog
. Depois de copiar o objeto do Realm, confirmamos que a cópia não é gerenciada e contém os dois objeto Frog
referenciados:
realm.writeBlocking { // Fetch the managed object you want to copy val managedPond = query<Pond>("name == $0", "Big Pond").find().first() assertTrue(managedPond.isManaged()) // Create an unmanaged copy of the object val unmanagedPond = copyFromRealm(managedPond) assertFalse(unmanagedPond.isManaged()) Log.v("Unmanaged pond name: ${unmanagedPond.name}") // Confirm the unmanaged copy contains all elements // in the copied object's RealmList val unmanagedFrogs = unmanagedPond.frogsThatLiveHere assertFalse(unmanagedFrogs[0].isManaged()) assertFalse(unmanagedFrogs[1].isManaged()) assertEquals(2, unmanagedFrogs.size) Log.v("Unmanaged frogs: ${unmanagedFrogs[0].name}, ${unmanagedFrogs[1].name}") }
Unmanaged pond name: Big Pond Unmanaged frogs: Kermit, Froggy Jay