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

CRUD - Leitura - Java SDK

Nesta página

  • Ler operações
  • Leia as características
  • Os resultados não são cópias
  • Os resultados são preguiçosos
  • As referências são retidas
  • Sobre os exemplos nesta página
  • Ler do Realm
  • Encontrar um objeto específico por chave primária
  • Consultar todos os objetos de dado específico
  • Filtrar consultas com base nas propriedades do objeto
  • Classificar Resultados da Consulta
  • Fazer query em um relacionamento
  • Consultar um Relacionamento Inverso
  • Dados agregados

Você pode ler os dados armazenados em Realm. O padrão de acesso a dados nos SDKs do Realm é localizar, filtrar e classificar objetos, nessa ordem. Para obter o melhor desempenho do Realm à medida que seu aplicativo cresce e suas queries se tornam mais complexas, crie os padrões de acesso a dados da sua aplicação em torno de uma sólida compreensão dascaracterísticas de leiturado Realm .

Quando você projeta os padrões de acesso a dados da sua aplicação em torno das três principais características de leituras a seguir no Realm, você pode ter certeza de que está lendo dados da forma mais eficiente possível.

Os resultados de uma consulta não são cópias de seus dados: a modificação dos resultados de uma consulta modificará diretamente os dados no disco. Esse mapeamento de memória também significa que os resultados são ativos: ou seja, eles sempre refletem o estado atual no disco.

O Realm adia a execução de uma query até que você acesse os resultados. Você pode encadear várias operações de filtro e classificação sem exigir trabalho extra para processar o estado intermediário.

Uma vantagem do modelo de objeto de Realm é que ele retém automaticamente todos os relacionamentos de um objeto como referências diretas, portanto você pode percorrer o grafo de relacionamentos diretamente por meio dos resultados de uma consulta.

Uma referência direta, ou ponteiro, permite que você acesse diretamente as propriedades de um objeto relacionado por meio da referência.

Outros bancos de dados geralmente copiam objetos do armazenamento do banco de dados para a memória do aplicativo quando você precisa trabalhar com eles diretamente. Como os objetos do aplicativo contêm referências diretas, você tem uma opção: copiar o objeto referido por cada referência direta para fora do banco de dados, caso seja necessário, ou apenas copiar a chave estrangeira de cada objeto e consultar o objeto com essa chave, se ele for acessado. Se você optar por copiar os objetos referenciados para a memória do aplicativo, poderá usar muitos recursos para objetos que nunca são acessados, mas se optar por copiar apenas a chave estrangeira, as pesquisas de objetos referenciados poderão causar lentidão no aplicativo.

O Realm contorna tudo isso com objetos ativos de cópia zero. Os acessadores de objeto de realm apontam diretamente para o armazenamento de banco de dados usando o mapeamento de memória, portanto não há distinção entre os objetos no Realm e os resultados da consulta na memória do aplicativo. Por isso você pode percorrer referências diretas em um domínio inteiro a partir de qualquer resultado de consulta.

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:

ProjectTask.java
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;
}
Project.java
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<>();
}
ProjectTask.kt
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()
Project.kt
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()

Uma leitura de um reino geralmente consiste nas seguintes etapas:

  • Obtenha todos os objetos de um determinado tipo do realm.

  • Opcionalmente, filtre os resultados usando o mecanismo de consulta.

  • Opcionalmente, classifique os resultados.

Todas as operações de consulta, filtro e classificação retornam uma coleção de resultados. As coleções de resultados estão ativas, o que significa que elas sempre contêm os resultados mais recentes da query associada.

Importante

Leituras e gravações síncronas na thread da interface do usuário

Por padrão, você só pode ler ou escrever em um realm no thread da UI do aplicativo usando transações assíncronas. Ou seja, você só pode usar métodos Realm cujo nome termina com a palavra Async no thread principal do seu aplicativo Android, a menos que você permita explicitamente o uso de métodos síncronos.

Essa restrição existe para o benefício dos usuários do aplicativo: executar operações de leitura e escrita no thread da interface do usuário pode levar a interações de interface do usuário não responsivas ou lentas, portanto, geralmente é melhor lidar com essas operações de forma assíncrona ou em um thread de fundo. No entanto, se o seu aplicativo exigir o uso de leituras ou gravações síncronas de realm no thread da interface do usuário, você poderá permitir explicitamente o uso de métodos síncronos com as seguintes opções SyncConfiguration:

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
);
}
});
val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v("EXAMPLE", "Successfully opened a realm with reads and writes allowed on the UI thread.")
}
})

Para encontrar um objeto com um valor de chave primária específico, abra um Realm e consulte o campo de chave primária para o valor de chave primária desejado usando o método RealmQuery.equalTo() método:

ProjectTask task = realm.where(ProjectTask.class).equalTo("_id", PRIMARY_KEY_VALUE.get()).findFirst();
Log.v("EXAMPLE", "Fetched object by primary key: " + task);
val task = realm.where(ProjectTask::class.java)
.equalTo("_id", ObjectId.get()).findFirst()
Log.v("EXAMPLE", "Fetched object by primary key: $task")

O primeiro passo de qualquer leitura é obter todos os objetos de um determinado tipo em um Realm. Com essa coleção de resultados, você pode operar em todas as instâncias em um tipo ou filtro e classificar para refinar os resultados.

Para acessar todas as instâncias de ProjectTask e Project, use o método onde() para especificar uma classe:

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
RealmQuery<Project> projectsQuery = realm.where(Project.class);
val tasksQuery = realm.where(ProjectTask::class.java)
val projectsQuery = realm.where(Project::class.java)

Um filtro seleciona um subconjunto de resultados com base nos valores de uma ou mais propriedades do objeto. O Realm oferece um mecanismo de query completo que você pode usar para definir filtros. O caso de uso mais comum é localizar objetos onde uma determinada propriedade corresponde a um determinado valor. Além disso, você pode comparar strings, agregar coleções de números e usar operadores lógicos para criar query complexas.

No exemplo a seguir, usamos operadores de comparação do mecanismo de consulta para:

  • Encontre tarefas de alta prioridade comparando o valor da propriedade priority com um número limite, acima do qual a prioridade pode ser considerada alta.

  • Encontre tarefas recém-iniciadas ou de curta duração verificando se a propriedade progressMinutes está dentro de um determinado intervalo.

  • Encontre tarefas não atribuídas encontrando tarefas onde a propriedade assignee é igual a nula.

  • Encontre tarefas atribuídas a membros específicos da equipe Ali ou Jamie verificando se a propriedade assignee está em uma lista de nomes.

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
Log.i("EXAMPLE", "High priority tasks: " + tasksQuery.greaterThan("priority", 5).count());
Log.i("EXAMPLE", "Just-started or short tasks: " + tasksQuery.between("progressMinutes", 1, 10).count());
Log.i("EXAMPLE", "Unassigned tasks: " + tasksQuery.isNull("assignee").count());
Log.i("EXAMPLE", "Ali or Jamie's tasks: " + tasksQuery.in("assignee", new String[]{"Ali", "Jamie"}).count());
val tasksQuery = realm.where(ProjectTask::class.java)
Log.i(
"EXAMPLE", "High priority tasks: " + tasksQuery.greaterThan(
"priority",
5
).count()
)
Log.i(
"EXAMPLE", "Just-started or short tasks: " + tasksQuery.between(
"progressMinutes",
1,
10
).count()
)
Log.i(
"EXAMPLE",
"Unassigned tasks: " + tasksQuery.isNull("assignee").count()
)
Log.i(
"EXAMPLE", "Ali or Jamie's tasks: " + tasksQuery.`in`(
"assignee", arrayOf(
"Ali",
"Jamie"
)
).count()
)

Uma operação de classificação permite configurar a ordem na qual o Realm retorna objetos consultados. A classificação pode ser feita com base em uma ou mais propriedades dos objetos na collection de resultados.

O Realm garante apenas uma ordem consistente de resultados quando os resultados são classificados.

O código a seguir classifica os projetos por nome em ordem alfabética inversa (ou seja, "ordem decrescente").

RealmQuery<Project> projectsQuery = realm.where(Project.class);
RealmResults<Project> results = projectsQuery.sort("name", Sort.DESCENDING).findAll();
val projectsQuery = realm.where(Project::class.java)
val results = projectsQuery.sort("name", Sort.DESCENDING).findAll()

Considere o seguinte relacionamento entre as classes Human e Cat. Este acordo permite que cada ser humano tenha um único cão:

import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class Human extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name;
private Cat cat;
public Human(String name) {
this.name = name;
}
public Human() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public ObjectId get_id() {
return _id;
}
}
import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.RealmResults;
import io.realm.annotations.LinkingObjects;
import io.realm.annotations.PrimaryKey;
public class Cat extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name = null;
@LinkingObjects("cat")
private final RealmResults<Human> owner = null;
public Cat(String name) {
this.name = name;
}
public Cat() {
}
public ObjectId get_id() {
return _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RealmResults<Human> getOwner() {
return owner;
}
}

Para consultar esse relacionamento, use a notação de ponto em um query para acessar qualquer propriedade do objeto vinculado :

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
);
realm.executeTransaction(transactionRealm -> {
Human owner = transactionRealm.where(Human.class).equalTo("cat.name", "bucky").findFirst();
Cat cat = owner.getCat();
Log.v("EXAMPLE", "Queried for humans with cats named 'bucky'. Found " + owner.getName() + ", who owns " + cat.getName());
});
realm.close();
}
});

Considere o seguinte relacionamento entre as classes Person e Dog. Esse acordo permite que cada pessoa tenha um único cachorro:

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import org.bson.types.ObjectId
open class Person(var name : String? = null) : RealmObject() {
@PrimaryKey
var _id : ObjectId = ObjectId()
var dog: Dog? = null
}
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
import org.bson.types.ObjectId
open class Dog(var name : String? = null): RealmObject() {
@PrimaryKey
var _id : ObjectId = ObjectId()
@LinkingObjects("dog")
val owner: RealmResults<Person>? = null
}

Para consultar esse relacionamento, use a notação de ponto em um query para acessar qualquer propriedade do objeto vinculado :

val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
)
realm.executeTransaction { transactionRealm ->
val owner = transactionRealm.where<Person>().equalTo("dog.name", "henry").findFirst()
val dog = owner?.dog
Log.v("EXAMPLE", "Queried for people with dogs named 'henry'. Found $owner, owner of $dog")
}
realm.close()
}
})

Considere o seguinte relacionamento entre as classes Cat e Human. Neste exemplo, todos os gatos estão vinculados a seu ser humano (ou a vários humanos, se vários objetos humanos se referirem ao mesmo cão). O Realm calcula os proprietários de cada animal para você com base no nome do campo fornecido à anotação @LinkingObjects :

import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.RealmResults;
import io.realm.annotations.LinkingObjects;
import io.realm.annotations.PrimaryKey;
public class Cat extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name = null;
@LinkingObjects("cat")
private final RealmResults<Human> owner = null;
public Cat(String name) {
this.name = name;
}
public Cat() {
}
public ObjectId get_id() {
return _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RealmResults<Human> getOwner() {
return owner;
}
}
import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class Human extends RealmObject {
@PrimaryKey
private ObjectId _id = new ObjectId();
private String name;
private Cat cat;
public Human(String name) {
this.name = name;
}
public Human() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public ObjectId get_id() {
return _id;
}
}

Para consultar esse relacionamento, use a notação de ponto em um query para acessar qualquer propriedade do objeto vinculado :

SyncConfiguration config = new SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build();
Realm.getInstanceAsync(config, new Realm.Callback() {
@Override
public void onSuccess(Realm realm) {
Log.v("EXAMPLE", "Successfully opened a realm.");
realm.executeTransaction(transactionRealm -> {
Cat cat = transactionRealm.where(Cat.class)
.equalTo("owner.name", "steven").findFirst();
Human owner = cat.getOwner().first();
Log.v("EXAMPLE", "Queried for cats with owners named 'steven'. Found " + cat.getName() + ", owned by " + owner.getName());
});
realm.close();
}
});

Considere o seguinte relacionamento entre as classes Dog e Person. Neste exemplo, todos os cães estão vinculados ao proprietário (ou a vários proprietários, se vários objetos de pessoa se referirem ao mesmo cão). O Realm calcula os proprietários de cada cão para você com base no nome do campo fornecido à anotação @LinkingObjects :

import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
import org.bson.types.ObjectId
open class Dog(var name : String? = null): RealmObject() {
@PrimaryKey
var _id : ObjectId = ObjectId()
@LinkingObjects("dog")
val owner: RealmResults<Person>? = null
}
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import org.bson.types.ObjectId
open class Person(var name : String? = null) : RealmObject() {
@PrimaryKey
var _id : ObjectId = ObjectId()
var dog: Dog? = null
}

Para consultar esse relacionamento, use a notação de ponto em um query para acessar qualquer propriedade do objeto vinculado :

val config = SyncConfiguration.Builder(app.currentUser(), PARTITION)
.allowQueriesOnUiThread(true)
.allowWritesOnUiThread(true)
.build()
Realm.getInstanceAsync(config, object : Realm.Callback() {
override fun onSuccess(realm: Realm) {
Log.v(
"EXAMPLE",
"Successfully opened a realm with reads and writes allowed on the UI thread."
)
realm.executeTransaction { transactionRealm ->
val dog = transactionRealm.where<Dog>()
.equalTo("owner.name", "dwayne").findFirst()
val owner = dog?.owner?.first()
Log.v("EXAMPLE", "Queried for dogs with owners named 'dwayne'. Found $dog, owned by $owner")
}
realm.close()
}
})
RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
/*
Aggregate operators do not support dot-notation, so you
cannot directly operate on a property of all of the objects
in a collection property.
You can operate on a numeric property of the top-level
object, however:
*/
Log.i("EXAMPLE", "Tasks average priority: " + tasksQuery.average("priority"));
val tasksQuery = realm.where(ProjectTask::class.java)
/*
Aggregate operators do not support dot-notation, so you
cannot directly operate on a property of all of the objects
in a collection property.
You can operate on a numeric property of the top-level
object, however:
*/Log.i("EXAMPLE", "Tasks average priority: " + tasksQuery.average("priority"))

Voltar

criar