Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
CRUD

CRUD - Lectura - Java SDK

Puedes leer los datos almacenados en Realm. El patrón estándar de acceso a datos en los SDK de Realm consiste en buscar, filtrar y ordenar objetos, en ese orden. Para obtener el máximo rendimiento de Realm a medida que tu aplicación crece y tus consultas se vuelven más complejas, diseña los patrones de acceso a datos de tu aplicación basándose en un conocimiento sólido de Realm. leer características.

When you design your app's data access patterns around the following three key characteristics of reads in Realm, you can be confident you are reading data as efficiently as possible.

Results to a query are not copies of your data: modifying the results of a query will modify the data on disk directly. This memory mapping also means that results are live: that is, they always reflect the current state on disk.

Realm defers execution of a query until you access the results. You can chain several filter and sort operations without requiring extra work to process the intermediate state.

One benefit of Realm's object model is that Realm automatically retains all of an object's relationships as direct references, so you can traverse your graph of relationships directly through the results of a query.

Una referencia directa, o puntero, te permite acceder directamente a las propiedades de un objeto relacionado a través de la referencia.

Otras bases de datos suelen copiar objetos del almacenamiento de la base de datos a la memoria de la aplicación cuando necesitas trabajar directamente con ellos. Debido a que los objetos de la aplicación contienen referencias directas, tienes la siguiente opción: copiar el objeto al que se hace referencia en cada referencia directa fuera de la base de datos en caso de que sea necesario, o simplemente copiar la clave externa de cada objeto y hacer query para el objeto con esa clave si se accede a él. Si eliges copiar objetos referenciados a la memoria de la aplicación, puedes usar muchos recursos para objetos a los que nunca se accede, pero si elige solo copiar la clave externa, las búsquedas de objetos referenciados pueden causar que su aplicación se vuelva lenta.

Realm bypasses all of this using zero-copy live objects. Realm object accessors point directly into database storage using memory mapping, so there is no distinction between the objects in Realm and the results of your query in application memory. Because of this, you can traverse direct references across an entire realm from any query result.

Los ejemplos de esta página utilizan el modelo de datos de una aplicación de gestión de proyectos que tiene dos tipos de objetos Realm: Project y Task. Un Project tiene cero o más Tasks.

See the schema for these two classes, Project and Task, below:

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()

A read from a realm generally consists of the following steps:

  • Obtener todos los objetos de un determinado tipo del reino.

  • Opcionalmente, filtre los resultados utilizando el motor de consulta.

  • Opcionalmente, ordena los resultados.

Todas las operaciones de consulta, filtrado y ordenación devuelven una colección de resultados. Estas colecciones están en tiempo real, lo que significa que siempre contienen los resultados más recientes de la consulta asociada.

Importante

Synchronous Reads and Writes on the UI Thread

By default, you can only read or write to a realm in your application's UI thread using asynchronous transactions. That is, you can only use Realm methods whose name ends with the word Async in the main thread of your Android application unless you explicitly allow the use of synchronous methods.

Esta restricción existe en beneficio de los usuarios de tu aplicación: realizar operaciones de lectura y escritura en el hilo de la Interfaz de Usuario puede generar interacciones lentas o no respondidas en la Interfaz de Usuario, por lo que generalmente es mejor gestionar estas operaciones de manera asíncrona o en un hilo en segundo plano. Sin embargo, si tu aplicación requiere el uso de lecturas o escrituras de realm síncronas en el hilo de la IU, puedes permitir explícitamente el uso de métodos síncronos con las siguientes opciones 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.")
}
})

To find an object with a specific primary key value, open a realm and query the primary key field for the desired primary key value using the RealmQuery.equalTo() method:

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")

El primer paso de cualquier lectura es obtener todos los objetos de un tipo determinado en un dominio. Con esta colección de resultados, se pueden operar en todas las instancias de un tipo o filtrar y ordenar para refinar los resultados.

Para acceder a todas las instancias de ProjectTask y,Project utilice el método where() para especificar una clase:

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)

Un filtro selecciona un subconjunto de resultados según el valor de una o más propiedades de un objeto. Realm ofrece un completo motor de consultas que permite definir filtros. El uso más común es encontrar objetos donde una propiedad determinada coincide con un valor específico. Además, permite comparar cadenas, agregar conjuntos de números y usar operadores lógicos para crear consultas complejas.

En el siguiente ejemplo, utilizamos los operadores de comparación del motor de consulta para:

  • Encuentre tareas de alta prioridad comparando el valor de la propiedad priority con un número umbral, por encima del cual la prioridad puede considerarse alta.

  • Find just-started or short-running tasks by seeing if the progressMinutes property falls within a certain range.

  • Find unassigned tasks by finding tasks where the assignee property is equal to null.

  • Find tasks assigned to specific teammates Ali or Jamie by seeing if the assignee property is in a list of names.

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()
)

A sort operation allows you to configure the order in which Realm returns queried objects. You can sort based on one or more properties of the objects in the results collection.

Realm solo garantiza un orden consistente de resultados cuando los resultados están ordenados.

El siguiente código ordena los proyectos por nombre en orden alfabético inverso (es decir, orden "descendente").

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 la siguiente relación entre las clases Human y Cat. Esta disposición permite que cada humano tenga un solo gato:

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 esta relación, utilice la notación de puntos en una consulta para acceder a cualquier propiedad del 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();
}
});

Consider the following relationship between classes Person and Dog. This arrangement allows each person to own a single dog:

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 esta relación, utilice la notación de puntos en una consulta para acceder a cualquier propiedad del 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 la siguiente relación entre las clases Cat y Human. En este ejemplo, todos los gatos se vinculan a su humano (o a varios humanos, si varios objetos humanos hacen referencia al mismo gato). Realm calcula automáticamente los propietarios de cada gato basándose en el nombre de campo que proporcione a la anotación @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 esta relación, utilice la notación de puntos en una consulta para acceder a cualquier propiedad del 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();
}
});

Consider the following relationship between classes Dog and Person. In this example, all dogs link to their owner (or multiple owners, if multiple person objects refer to the same dog). Realm calculates the owners of each dog for you based on the field name you provide to the @LinkingObjects annotation:

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 esta relación, utilice la notación de puntos en una consulta para acceder a cualquier propiedad del 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"))

Volver

Crear