Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ / /

Atualizar objetos de domínio - Kotlin SDK

Nesta página

  • Atualizar operações
  • Atualizar um objeto existente
  • Atualizar um objeto de realm
  • Atualizar um Objeto Embarcado
  • Atualizar vários objetos
  • Atualizar propriedades do domínio
  • Atualizar uma propriedade MutableRealmInt (Contador)
  • Atualizar uma propriedade RealmAny (Misto)
  • Atualizar propriedades da coleção
  • Atualizar um RealmList
  • Atualizar um RealmSet
  • Atualizar um dicionário
  • Atualizar relacionamentos
  • Atualizar um relacionamento entre um e outro
  • Atualizar um relacionamento para muitos
  • Atualizar uma relação inversa
  • Fazer Upsert de um Objeto de Realm

Esta página descreve como atualizar um objeto de Realm existente em um domínio local ou sincronizado usando o Kotlin SDK. Para saber mais sobre como criar objetos em um domínio, consulte Criar objetos do Realm - Kotlin SDK.

O Realm oferece suporte a operações de atualização e upsert em objetos do Realm e objetos incorporados. Uma operação upsert insere uma nova instância de um objeto ou atualiza um objeto existente que atende a determinados critérios. Para obter mais informações, consulte a seção Upsert a Realm Object nesta página.

Você não pode atualizar objetos assimétricos. Isso ocorre porque objetos assimétricos são objetos especiais somente para gravação que não persistem no domínio. Para obter informações sobre como usar objetos assimétricos em seu aplicativo, consulte Stream Data to Atlas -Kotlin SDK.

Observação

Escreva para um domínio sincronizado

A sintaxe para atualizar um objeto em um domínio é a mesma para um domínio local ou sincronizado. No entanto, há considerações adicionais que determinam se a operação de gravação em um domínio sincronizado é bem-sucedida. Para obter mais informações, consulte Gravar dados em um realm sincronizado - Kotlin SDK.

Todas as operações que modificam um realm - inclusive as operações de atualização e upsert, devem ser realizadas dentro de uma transação de gravação. As transações de gravação são passadas para o método write() ou writeBlocking() do realm. Nesse retorno de chamada, você pode acessar uma instância MutableRealm e, em seguida, atualizar objetos dentro do realm. Para obter mais informações sobre transações de gravação e como o realm as trata, consulte Transações de gravação.

Além disso, você só pode modificar objetos ativos, que só são acessíveis dentro de uma transação de gravação. Você pode converter um objeto congelado em um objeto ativo em uma transação com mutableRealm.findLatest().

Exemplo

Converter objeto congelado antes de modificar

val frozenFrog = realm.query<Frog>().find().first()
// Open a write transaction
realm.write {
// Get the live frog object with findLatest(), then update it
findLatest(frozenFrog)?.let { liveFrog ->
liveFrog.name = "Kermit"
liveFrog.age -= 1
}
}

Para modificar as propriedades de um objeto de Realm ou objeto incorporado armazenado em um domínio:

  1. Abra uma transação de gravação com realm.write() ou realm.writeBlocking().

  2. Obtenha os objetos ativos consultando o realm mutável da transação para os objetos que você deseja modificar usando query():

    1. Especifique o tipo de objeto como um parâmetro de tipo passado para query().

    2. (Opcional) Filtre o conjunto de objetos retornados especificando uma query. Se você não incluir um filtro de query, retornará todos os objetos do tipo especificado. Para obter mais informações sobre a query com o Kotlin SDK, consulte Read Realm Objects - Kotlin SDK.

    Importante

    Objetos devem estar ao vivo

    Você só pode modificar objetos ao vivo. Se sua query ocorrer fora da transação de escrita, você deverá converter os objetos congelados em objetos ativos na transação com mutableRealm.findLatest().

  3. Modifique o objeto dentro da transação de gravação. Você pode usar um bloco de aplicação para configurar várias propriedades de uma só vez. Todas as alterações são automaticamente mantidas no Realm quando o Realm confirma a transação de gravação.

Observação

Atualizando Strings ou Matrizes de Bytes

Como o Realm opera em campos como um todo, não é possível atualizar diretamente elementos individuais de strings ou arrays de bytes. Em vez disso, é necessário ler o campo inteiro, fazer a modificação em elementos individuais e, em seguida, gravar o campo inteiro novamente em um bloco de transação.

Para atualizar um objeto de Realm, consulte o tipo usando um filtro que retorna o objeto específico que você deseja atualizar. Em seguida, modifique as propriedades do objeto.

Dica

Usar informações de identificação exclusivas

Recomendamos filtrar com informações de identificação exclusivas, como um valor de chave primária, para garantir que sua query retorne o objeto correto.

No exemplo a seguir, executamos query de um objeto Frog por chave primária e, em seguida, atualizamos as propriedades name e age:

// Query and update a realm object in a single write transaction
realm.write {
val liveFrog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
liveFrog.name = "Michigan J. Frog"
liveFrog.age += 1
}

Você pode atualizar um objeto incorporado modificando propriedades individuais ou substituindo todo o objeto incorporado.

Dica

Acesse objetos incorporados com notação de ponto

Você pode usar a notação de pontos para acessar as propriedades do objeto embarcado como se estivesse em um objeto normal aninhado. Para obter mais informações, consulte Filtrar por propriedade de objeto embarcado.

Para atualizar uma ou mais propriedades em um objeto incorporado, busque o objeto pai ou incorporado e reatribua as propriedades do objeto incorporado em uma transação de escrita.

No exemplo a seguir, temos um objeto Contact que contém um objeto EmbeddedAddress incorporado. Atualizamos as propriedades de objeto incorporadas em várias operações:

// Modify embedded object properties in a write transaction
realm.write {
// Fetch the objects
val addressToUpdate = findLatest(address) ?: error("Cannot find latest version of embedded object")
val contactToUpdate = findLatest(contact) ?: error("Cannot find latest version of parent object")
// Update a single embedded object property directly
addressToUpdate.street = "100 10th St N"
// Update multiple properties
addressToUpdate.apply {
street = "202 Coconut Court"
city = "Los Angeles"
state = "CA"
postalCode = "90210"
}
// Update property through the parent object
contactToUpdate.address?.state = "NY"
}

Para substituir completamente um objeto incorporado, atribua uma nova instância de objeto incorporado à propriedade principal em uma transação de escrita. Isso exclui o objeto incorporado existente.

No exemplo a seguir, temos um objeto Contact que contém um objeto EmbeddedAddress incorporado. Definimos um novo objeto EmbeddedAddress e o atribuímos à propriedade principal:

realm.write {
val parentObject = query<Contact>("_id == $0", PRIMARY_KEY_VALUE).find().first()
val newAddress = EmbeddedAddress().apply {
propertyOwner = Contact().apply { name = "Michigan J. Frog" }
street = "456 Lily Pad Ln"
country = EmbeddedCountry().apply { name = "Canada" }
}
// Overwrite the embedded object with the new instance (deletes the existing object)
parentObject.address = newAddress
}

Você também pode atualizar vários objetos em um domínio:

  1. Executar queries de um realm para uma coleção de objetos com realm.query().

  2. Abra uma transação de gravação com realm.write() ou realm.writeBlocking().

  3. Atualiza os elementos do conjunto de RealmResults retornados pela query.

val tadpoles = realm.query<Frog>("age <= $0", 2)
for (tadpole in tadpoles.find()) {
realm.write {
findLatest(tadpole)?.name = tadpole.name + " Jr."
}
}

Dependendo de como você define o seu tipo de objeto, você pode ter propriedades que são tiposespeciais específicos do Realm.

Você pode utilizar as seguintes funções de API do Realm para atualizar um valor de propriedade MutableRealmInt:

  • increment()

  • decrement()

  • set()

Estes métodos retornam a propriedade MutableRealmInt com um valor mutado.

Dica

Use o operador set() com cuidado

O operador set() substitui quaisquer chamadas anteriores para increment() ou decrement(). Não recomendamos misturar set() com increment() ou decrement(), a menos que a contagem difusa seja aceitável para seu caso de uso.

Além das funções da API Realm , você também pode usar o seguinte conjunto de operadores e funções infix semelhantes às fornecidas pela biblioteca padrão do Kotlin para Long:

  • Operadores de prefixo unário: unaryPlus, unaryMinus

  • Operadores de aumento e decremento: inc, dec (não deve ser confundido com increment e decrement)

  • Operadores aritméticos: plus, minus, times, div, rem

  • Operadores de qualidade: equals

  • Operadores de comparação: compareTo

  • Bitwise functions: shl, shr, ushr, and, or, xor, inv

No entanto, esses operadores e funções infix não mutam a instância na qual são chamados. Em vez disso, eles retornam uma nova instância não gerenciada com o resultado da operação.

Importante

Somente métodos de domínio resultam em um valor mutado

As únicas operações que resultam em um valor mutado são as funções da API do Realm: increment, decrement e set. Todas as outras operações (incluindo inc e dec) retornam uma instância não gerenciada com um novo valor.

No exemplo seguinte, atualizamos uma propriedade MutableRealmInt com operações increment(), decrement() e set():

// Open a write transaction
realm.write {
// Get the live object
val frog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
val counter: MutableRealmInt? = frog.fliesEaten
counter?.get() // 1
// Increment the value of the MutableRealmInt property
// ** Note use of decrement() with negative value **
counter?.increment(0) // 1
counter?.increment(5) // 6
counter?.decrement(-2) // 8
// Decrement the value of the MutableRealmInt property
// ** Note use of increment() with negative value **
counter?.decrement(0) // 8
counter?.decrement(2) // 6
counter?.increment(-1) // 5
// Set the value of the MutableRealmInt property
// ** Use set() with caution **
counter?.set(0)// 0
}

As propriedades do RealmAny são imutáveis. Para atualizar um valor RealmAny , você deve criar uma nova instância da propriedade com o valor e tipo desejados. Para mais informações sobre como adicionar propriedades do RealmAny , consulte Criar uma propriedade RealmAny (Misto).

Adicionalmente, você deve conhecer o tipo armazenado para extrair o valor de uma propriedade RealmAny. Se você chamar um método de getter com o tipo errado, o Realm lança uma exceção.

Dica

Lidar com polimorfismo com expressões condicionais

Como você precisa conhecer o tipo armazenado para extrair seu valor, recomendamos o uso de uma expressão when para lidar com o tipo RealmAny e sua possível classe de valor interna.

val favoriteThings = frog.favoriteThings
when (favoriteThings.type) {
INT -> rating(favoriteThings.asInteger())
STRING -> description(favoriteThings.asString())
BYTE_ARRAY -> image(favoriteThings.asByteArray())
// Handle other possible types...
else -> {
// Debug or a perform default action
Log.d("ExampleHandler", "Unhandled type: ${favoriteThings.type}")
}
}

No exemplo a seguir, atualizamos um objeto Frog que contém uma lista de propriedades do RealmAny criando novas instâncias de cada elemento de lista:

// Find favoriteThing that is an Int
// Convert the value to Double and update the favoriteThing property
realm.write {
val kermit = query<Frog>().find().first()
val realmAny: RealmList<RealmAny?> = kermit.favoriteThings
for (i in realmAny.indices) {
val thing = realmAny[i]
if (thing?.type == RealmAny.Type.INT) {
val intValue = thing.asInt()
val doubleValue = intValue.toDouble()
realmAny[i] = RealmAny.create(doubleValue)
}
}
}
// Overwrite all existing favoriteThing properties
// ** Null clears the property value **
realm.write {
val frog = query<Frog>().find().first()
val realmAny: RealmList<RealmAny?> = frog.favoriteThings
realmAny[0] = RealmAny.create("sunshine")
realmAny[1] = RealmAny.create(Frog().apply { name = "Kermit Sr." })
realmAny[2] = null
}

Observação

Limpar um RealmQualquer valor de propriedade com nulo

Você pode atribuir null diretamente a uma propriedade RealmAny para remover o valor atual.

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

As coleções são mutáveis e contam com o apoio de suas classes Kotlin incorporadas correspondentes. Você pode adicionar e remover elementos em uma coleção dentro de uma transação por escrito.

Dica

Ouça as alterações em uma coleção

Você pode registrar um manipulador de notificações para ouvir as alterações. Para mais informações, consulte Registrar um Listener de Alteração de Coleção.

Você pode atualizar elementos em uma RealmList como faria com uma Kotlin MutableList.

No exemplo a seguir, atualizamos os elementos RealmList para um objeto Frog existente:

realm.write {
// Get the live object
val realmList = query<Frog>("name = $0", "Kermit").first().find()!!.favoritePonds
realmList[0].name = "Picnic Pond"
realmList.set(1, Pond().apply { name = "Big Pond" })
}

Para mais informações sobre adicionar e remover elementos do RealmList, consulte Criar uma RealmList e Remover Elementos de uma RealmList.

Você pode adicionar, atualizar e remover elementos em um RealmSet como faria com um Kotlin MutableSet.

No exemplo a seguir, iteramos e atualizamos RealmSet elementos para objetos Frog existentes:

// Find a frog in the realm
val kermit = realm.query<Frog>("name = $0", "Kermit").find().first()
val realmSet = kermit.favoriteSnacks
// Update the name of each snack in the set
for (snack in realmSet) {
realm.write {
findLatest(snack)?.name = snack.name.uppercase()
}
}
realm.write {
// Find all frogs who like rain
val frogsWhoLikeRain = realm.query<Frog>("favoriteWeather CONTAINS $0", "rain").find()
// Add thunderstorms to their favoriteWeather set
for (frog in frogsWhoLikeRain) {
val latestFrog = findLatest(frog)
latestFrog?.favoriteWeather?.add("thunderstorms")
}
}

Para mais informações sobre adicionar e remover elementos do RealmSet, consulte Criar uma Propriedade do RealmSet e Remover Elementos de um RealmSet.

Você pode atualizar chaves e valores em um RealmDictionary como faria com um Kotlin MutableMap.

No exemplo a seguir, atualizamos um RealmDictionary

// Find frogs who have forests with favorite ponds
val thisFrog = realm.query<RealmDictionary_Frog>("favoritePondsByForest.@count > 1").find().first()
// Update the value for a key if it exists
if (thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) {
realm.write {
findLatest(thisFrog)?.favoritePondsByForest?.set("Lothlorien", "Lily Pad Pond")
}
}
// Add a new key-value pair
realm.write {
findLatest(thisFrog)?.favoritePondsByForest?.put("Sherwood Forest", "Miller Pond")
}

Para obter mais informações sobre como adicionar e remover entradas do RealmDictionary, consulte Criar uma propriedade de dicionário e Remover chaves/valores de dicionário.

Dependendo de como você define seu tipo de objeto, você pode ter propriedades que referenciam outro objeto do Realm. Isso pode ser uma relação para-um, para-muitos ou inversa.

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 obter mais informações, consulte a seção Atualizar um objeto incorporado nesta página.

Você pode atualizar relações entre objetos em um território modificando as propriedades que definem a relação da mesma forma que atualizaria qualquer outra propriedade.

No exemplo a seguir, temos um objeto Frog com uma propriedade favoritePond que referencia um único objeto Pond e uma propriedade bestFriend que referencia outro objeto Frog:

realm.write {
val kermit = query<Frog>("name == $0", "Kermit").find().first()
// Update a property on the related object
kermit.favoritePond?.name = "Big Pond"
// Assign a new related object
val newBestFriend = Frog().apply { name = "Froggy Jr." }
kermit.bestFriend = newBestFriend
}

Você pode atualizar relacionamentos para muitos da mesma forma que atualizaria qualquer outra coleção. Consulte a seção Atualizar propriedades da coleção nesta página.

No exemplo seguinte, temos um 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 {
val forest = query<Forest>().find().first()
// Update a property on a related object in the set
forest.frogsThatLiveHere.first().name = "Kermit Sr."
// Add a new related object to the list
forest.frogsThatLiveHere.add(Frog().apply { name = "Froggy Jr." })
}

Você pode acessar e atualizar objetos em um relacionamento inverso. No entanto, você não pode modificar diretamente a coleção de backlink em si. Em vez disso, o Realm atualiza automaticamente o relacionamento implícito quando você modifica quaisquer objetos relacionados. Para mais informações, consulte Definir um relacionamento inverso.

No exemplo a seguir, temos um objeto principal User com uma propriedade backlinks posts que faz referência a uma lista de objetos secundários Post. Atualizamos propriedades nos objetos principal e secundário por meio do backlink:

realm.write {
// Update child objects through the parent
val parent = query<User>().find().first()
parent.posts[0].title = "Forest Life Vol. 2"
parent.posts.add(Post().apply { title = "Forest Life Vol. 3" })
// Update child objects (Realm automatically updates the backlink collection)
val child = query<Post>("title == $0", "Top Ponds of the Year!").find().first()
child.title = "Top Ponds of the Year! Vol. 2"
assertEquals("Top Ponds of the Year! Vol. 2", parent.posts[1].title)
// Update the parent object through the child
child.user[0].name = "Kermit Sr."
// ** You CANNOT directly modify the backlink collection **
val readOnlyBacklink: RealmResults<User> = child.user
}

Para fazer upsert de um objeto em um realm, insira um objeto com uma chave primária usando copyToRealm(), como faria ao criar um novo objeto, e passe um parâmetro UpdatePolicy para especificar como o SDK lida com objetos existentes com a mesma chave primária:

  • UpdatePolicy.ALL: Atualize todas as propriedades em quaisquer objetos existentes identificados com a mesma chave primária.

  • UpdatePolicy.ERROR (padrão): não permitir a atualização de objetos existentes e, em vez disso, lançar uma exceção se um objeto já existir com a mesma chave primária. Se você não especificar uma política de atualização, o Realm usará essa política por padrão.

O seguinte pode ocorrer dependendo da política de atualização:

  • Se não houver nenhum objeto que corresponda à chave primária, o SDK inserirá o novo objeto.

  • Se já existir um objeto com a mesma chave primária, o SDK:

    • Atualiza todas as propriedades em quaisquer objetos existentes identificados com a mesma chave primária. Observe que as propriedades são marcadas como atualizadas nos ouvintes de alterações, mesmo que a propriedade tenha sido atualizada com o mesmo valor.

    • Lança uma exceção indicando que um objeto já existe no domínio.

No exemplo a seguir, tentamos inserir um objeto Frog com uma chave primária que já existe no domínio com UpdatePolicy.ALL e confirmamos que o objeto foi inserido com sucesso:

realm.write {
val existingFrog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
assertEquals(existingFrog.name, "Kermit")
// Use copyToRealm() to insert the object with the primary key
// ** UpdatePolicy determines whether to update or throw an error if object already exists**
copyToRealm(Frog().apply {
_id = PRIMARY_KEY_VALUE
name = "Wirt"
age = 4
species = "Greyfrog"
owner = "L'oric"
}, UpdatePolicy.ALL)
val upsertFrog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
assertEquals(upsertFrog.name, "Wirt")
}

Voltar

Leia