Os exemplos nesta página usam o Modelo de dados Realm de um aplicativo de gerenciamento de projeto que tem dois Tipo de objeto de Realm: Project
e Task
. Um Project
tem zero ou mais Tasks
.
Consulte o esquema para estas duas classes, Project
e Task
, abaixo:
import org.bson.types.ObjectId; |
|
import io.realm.RealmObject; |
import io.realm.annotations.PrimaryKey; |
import io.realm.annotations.RealmClass; |
import io.realm.annotations.Required; |
|
public class ProjectTask extends RealmObject { |
@PrimaryKey |
public ObjectId _id; |
@Required |
public String name; |
public String assignee; |
public int progressMinutes; |
public boolean isComplete; |
public int priority; |
@Required |
public String _partition; |
} |
import org.bson.types.ObjectId; |
|
import io.realm.RealmList; |
import io.realm.RealmObject; |
import io.realm.annotations.PrimaryKey; |
import io.realm.annotations.RealmClass; |
import io.realm.annotations.Required; |
|
public class Project extends RealmObject { |
@PrimaryKey |
public ObjectId _id; |
@Required |
public String name; |
public RealmList<ProjectTask> tasks = new RealmList<>(); |
} |
import io.realm.RealmObject |
import io.realm.annotations.PrimaryKey |
import io.realm.annotations.Required |
import org.bson.types.ObjectId |
|
open class ProjectTask( |
@PrimaryKey |
var _id: ObjectId = ObjectId(), |
@Required |
var name: String = "", |
var assignee: String? = null, |
var progressMinutes: Int = 0, |
var isComplete: Boolean = false, |
var priority: Int = 0, |
var _partition: String = "" |
): RealmObject() |
import io.realm.RealmList |
import io.realm.RealmObject |
import io.realm.annotations.PrimaryKey |
import io.realm.annotations.Required |
import org.bson.types.ObjectId |
|
open class Project( |
@PrimaryKey |
var _id: ObjectId = ObjectId(), |
@Required |
var name: String = "", |
var tasks: RealmList<ProjectTask> = RealmList(), |
): RealmObject() |
Em uma transação, você pode atualizar um Objeto de Realm da mesma forma que atualizaria qualquer outro objeto no idioma de sua escolha. Basta atribuir um novo valor à propriedade ou atualizar a propriedade.
O exemplo a seguir altera o nome da tarde para "Archibald" e define a idade de Arquibald para 101 ao atribuir novos valores às propriedades:
realm.executeTransaction(r -> { |
|
Turtle turtle = r.where(Turtle.class).findFirst(); |
|
|
turtle.setName("Archibald"); |
turtle.setAge(101); |
}); |
realm.executeTransaction { r: Realm -> |
|
val turtle = r.where(Turtle::class.java).findFirst() |
|
|
turtle!!.name = "Archibald" |
turtle.age = 101 |
} |
Um upsert é uma operação de gravação que insere um novo objeto com uma determinada chave primária ou atualiza um objeto existente que já tem essa chave primária. Chamamos isso de upsert porque é uma operação de "atualização ou inserção". Isso é útil quando um objeto pode ou não existir, como ao importar em massa um conjunto de dados para um Realm existente. O upserting é uma maneira elegante de atualizar as entradas existentes e adicionar novas entradas.
O exemplo a seguir demonstra como fazer o upsert de um objeto com Realm. Criamos um novo impulsionador de conchas chamado "Drew" e atualizamos seu nome para "Andy" usando insertOrUpdate():
realm.executeTransaction(r -> { |
ObjectId id = new ObjectId(); |
TurtleEnthusiast drew = new TurtleEnthusiast(); |
drew.set_id(id); |
drew.setName("Drew"); |
drew.setAge(25); |
|
|
r.insertOrUpdate(drew); |
TurtleEnthusiast andy = new TurtleEnthusiast(); |
andy.set_id(id); |
andy.setName("Andy"); |
andy.setAge(56); |
|
|
r.insertOrUpdate(andy); |
}); |
realm.executeTransaction { r: Realm -> |
val id = ObjectId() |
val drew = TurtleEnthusiast() |
drew._id = id |
drew.name = "Drew" |
drew.age = 25 |
|
|
r.insertOrUpdate(drew) |
val andy = TurtleEnthusiast() |
andy._id = id |
andy.name = "Andy" |
andy.age = 56 |
|
|
r.insertOrUpdate(andy) |
} |
Você também pode usar copyToRealmOrUpdate() para criar um novo objeto com base em um objeto fornecido ou atualizar um objeto existente com o mesmo valor de chave primária . Utilize o CHECK_SAME_VALUES_BEFORE_SET
ImportFlag para atualizar somente os campos que são diferentes no objeto fornecido:
O exemplo a seguir demonstra como inserir um objeto ou, se já existir um objeto com a mesma chave primária, atualizar apenas os campos que diferem:
realm.executeTransaction(r -> { |
ObjectId id = new ObjectId(); |
TurtleEnthusiast drew = new TurtleEnthusiast(); |
drew.set_id(id); |
drew.setName("Drew"); |
drew.setAge(25); |
|
|
r.insertOrUpdate(drew); |
TurtleEnthusiast andy = new TurtleEnthusiast(); |
andy.set_id(id); |
andy.setName("Andy"); |
|
|
|
r.copyToRealmOrUpdate(andy, ImportFlag.CHECK_SAME_VALUES_BEFORE_SET); |
}); |
realm.executeTransaction { r: Realm -> |
val id = ObjectId() |
val drew = TurtleEnthusiast() |
drew._id = id |
drew.name = "Drew" |
drew.age = 25 |
|
|
r.insertOrUpdate(drew) |
val andy = TurtleEnthusiast() |
andy._id = id |
andy.name = "Andy" |
|
|
r.copyToRealmOrUpdate(andy, |
ImportFlag.CHECK_SAME_VALUES_BEFORE_SET) |
} |
O Realm suporta atualizações de toda a coleção. Uma atualização de collection aplica a mesma atualização a propriedades específicas de vários objetos em uma collection de uma só vez.
O exemplo a seguir demonstra como atualizar uma coleção. Graças à relação inversa implícita entre a propriedade owner
do Mongophyllum e a propriedade turtles
do Mongophyllum, o Realm atualiza automaticamente a lista de réplicas de Giphyllum
realm.executeTransaction(r -> { |
|
TurtleEnthusiast josephine = r.createObject(TurtleEnthusiast.class, new ObjectId()); |
josephine.setName("Josephine"); |
|
|
RealmResults<Turtle> turtles = r.where(Turtle.class).equalTo("name", "Pierogi").findAll(); |
|
|
turtles.setObject("owner", josephine); |
}); |
realm.executeTransaction { r: Realm -> |
|
val josephine = realm.createObject( |
TurtleEnthusiast::class.java, |
ObjectId() |
) |
josephine.name = "Josephine" |
|
|
val turtles = r.where(Turtle::class.java) |
.equalTo("name", "Pierogi") |
.findAll() |
|
|
turtles.setObject("owner", josephine) |
} |
Como as collection do Realm sempre refletem o estado mais recente, elas podem aparecer, desaparecer ou alterar enquanto você itera sobre uma collection. Para obter uma collection estável na qual você pode iterar, você pode criar um instantâneo dos dados de uma collection. Um snapshot garante que a ordem dos elementos não será alterada, mesmo que um elemento seja excluído ou modificado.
Iterator
objetos criados a partir de RealmResults
usam snapshots automaticamente. Objetos Iterator
criados a partir de instâncias RealmList
não usam snapshots. Use RealmList.createSnapshot() ou RealmResults.createSnapshot() para gerar manualmente um snapshot que você pode iterar manualmente:
O exemplo a seguir demonstra como iterar uma collection com segurança usando um snapshot implícito criado a partir de um RealmResults
Iterator
ou um snapshot manual criado a partir de um RealmList
:
RealmResults<Frog> frogs = realm.where(Frog.class) |
.equalTo("species", "bullfrog") |
.findAll(); |
|
|
realm.executeTransaction(r -> { |
for (Frog frog : frogs) { |
frog.setSpecies("Lithobates catesbeiana"); |
} |
}); |
|
|
realm.executeTransaction(r -> { |
OrderedRealmCollectionSnapshot<Frog> frogsSnapshot = frogs.createSnapshot(); |
for (int i = 0; i < frogsSnapshot.size(); i++) { |
frogsSnapshot.get(i).setSpecies("Lithobates catesbeiana"); |
} |
}); |
val frogs = realm.where(Frog::class.java) |
.equalTo("species", "bullfrog") |
.findAll() |
|
|
realm.executeTransaction { |
for (frog in frogs) { |
frog.species = "Lithobates catesbeiana" |
} |
} |
|
|
realm.executeTransaction { |
val frogsSnapshot = frogs.createSnapshot() |
for (i in frogsSnapshot.indices) { |
frogsSnapshot[i]!!.species = "Lithobates catesbeiana" |
} |
} |