Overview
En esta guía, puede aprender a usar el driver de Java Reactive Streams para almacenar y recuperar datos modelados por objetos Java comunes, o POJO. Los POJO se suelen utilizar para la encapsulación de datos, que es la práctica de separar la lógica empresarial de la representación de datos.
Tip
Para aprender más información sobre los POJO, consulte la entrada de Wikipedia Plain old Java objeto.
Esta guía muestra cómo realizar las siguientes tareas:
Configure el controlador para serializar y deserializar POJOs
Realizar operaciones CRUD mediante datos modelados por POJOs
Importante
Esta guía utiliza implementaciones personalizadas de Subscriber, que se describen en la guía Implementaciones personalizadas de suscriptores de muestra.
Muestra de POJO
Los ejemplos de esta guía utilizan las clases POJO Person y Address para modelar documentos en una colección de muestra denominada people.
La clase Person almacena el nombre, la edad y la dirección de una persona. Esta clase tiene la siguiente definición:
import org.bson.types.ObjectId; public final class Person { private ObjectId id; private String name; private int age; private Address address; public Person() {} public Person(final String name, final int age, final Address address) { this.name = name; this.age = age; this.address = address; } public ObjectId getId() { return id; } public void setId(final ObjectId id) { this.id = id; } public String getName() { return name; } public void setName(final String name) { this.name = name; } public int getAge() { return age; } public void setAge(final int age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(final Address address) { this.address = address; } public String toString() { return "Person{" + "id='" + id + "'" + ", name='" + name + "'" + ", age=" + age + ", address=" + address + "}"; } }
La clase Address almacena una calle, ciudad y código postal. Esta clase tiene la siguiente definición:
public final class Address { private String street; private String city; private String zip; public Address() {} public Address(final String street, final String city, final String zip) { this.street = street; this.city = city; this.zip = zip; } public String getStreet() { return street; } public void setStreet(final String street) { this.street = street; } public String getCity() { return city; } public void setCity(final String city) { this.city = city; } public String getZip() { return zip; } public void setZip(final String zip) { this.zip = zip; } public String toString() { return "Address{" + "street='" + street + "'" + ", city='" + city + "'" + ", zip='" + zip + "'" + "}"; } }
Cuando defina una clase POJO, asegúrese de cumplir los siguientes requisitos:
La clase POJO no puede implementar interfaces ni extender clases de un framework.
Incluye todos los campos para los que quieras almacenar y recuperar datos, y asegúrate de que no estén marcados como
staticotransient.Si incluye métodos getter o setter públicos siguiendo las convenciones de nomenclatura de JavaBean, el driver los llama al serializar o deserializar datos. Si omite los métodos getter o setter para un campo público, el driver accede o los asigna directamente.
Configura el controlador para POJO
Antes de poder usar un POJO con el driver de Java Reactive Streams, debe configurarlo para serializar y deserializar POJO creando un CodecRegistry personalizado. Los siguientes pasos muestran cómo crear el CodecRegistry y aplicarlo a un cliente, base de datos o colección.
Cree un CodecRegistry.
Cree un CodecRegistry que combine el registro de códecs por defecto con el PojoCodecProvider, como se muestra en el siguiente código:
CodecRegistry pojoCodecRegistry = fromRegistries( getDefaultCodecRegistry(), fromProviders(pojoCodecProvider) );
Nota
Los registros se comprueban en orden hasta que uno devuelve un códec para la clase solicitada. Incluya primero el registro de códecs por defecto en la lista e incluya el PojoCodecProvider último porque puede proporcionar un códec para casi cualquier clase.
Aplica el CodecRegistry.
Configure una instancia MongoClient, MongoDatabase o MongoCollection para usar el CodecRegistry personalizado. Puede establecer el registro de códecs de una de las siguientes maneras:
Establezca el
CodecRegistryen unMongoClient:MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(pojoCodecRegistry) .build(); Establezca el
CodecRegistryen unMongoDatabase:MongoDatabase database = mongoClient.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry); Establezca el
CodecRegistryen unMongoCollection:MongoCollection<org.bson.Document> rawCollection = database.getCollection("people").withCodecRegistry(pojoCodecRegistry);
Obtener una colección tipada.
Pase su clase POJO a getCollection() como parámetro de clase de documento y especifíquela como el argumento de tipo de su instancia MongoCollection, como se muestra en el siguiente código:
MongoCollection<Person> collection = database.getCollection("people", Person.class);
Realizar operaciones CRUD
Después de configurar el driver para utilizar el POJO Person, puede realizar operaciones CRUD en los datos modelados por el POJO.
Insert Data
El registro de códecs crea automáticamente un POJO Codec para clases desconocidas, lo que le permite utilizar POJO listos para usar sin configuración extra.
Para insertar un solo Person en la colección, llame al método insertOne() y suscríbase al resultado. El siguiente ejemplo inserta una instancia de Person llamada ada en la colección people:
Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1")); collection.insertOne(ada).subscribe(new OperationSubscriber<InsertOneResult>());
Para insertar varias instancias de Person, llame al método insertMany() y pase una lista de instancias, como se muestra en el siguiente ejemplo:
List<Person> people = asList( new Person("Charles Babbage", 45, new Address("5 Devonshire Street", "London", "W11")), new Person("Alan Turing", 28, new Address("Bletchley Hall", "Bletchley Park", "MK12")), new Person("Timothy Berners-Lee", 61, new Address("Colehill", "Wimborne", null)) ); collection.insertMany(people).subscribe(new OperationSubscriber<InsertManyResult>());
Datos de query
Para query la colección, utilice el método find(). Puede pasar un objeto de filtro al método find() para recuperar documentos que coincidan con ciertas condiciones. El driver proporciona Filters métodos asistente que puede utilizar para crear objetos de filtro.
Importante
Al hacer query a POJO, debes hacer query contra el nombre del campo del documento y no contra el nombre de la propiedad de POJO. Por defecto son iguales, pero es posible cambiar cómo se asignan los nombres de las propiedades POJO.
Retrieve One
Para recuperar la primera instancia Person que coincida con un filtro, llame al método first() en el resultado de una operación find().
El siguiente ejemplo recupera la primera instancia Person que tiene un valor de campo address.city de "Wimborne":
collection.find(eq("address.city", "Wimborne")) .first() .subscribe(new PrintToStringSubscriber<>());
Person{id='...', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
Recuperar múltiples
Para recuperar todas las instancias de Person que coinciden con un filtro, llame al método find() y suscríbase a los resultados.
El siguiente ejemplo recupera cada instancia Person que tiene un valor de campo age mayor que 30:
collection.find(gt("age", 30)).subscribe(new PrintToStringSubscriber<>());
Person{id='...', name='Charles Babbage', age=45, address=Address{street='5 Devonshire Street', city='London', zip='W11'}} Person{id='...', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
Actualizar datos
Para actualizar documentos en una colección, utilice los métodos updateOne() y updateMany(). Pase los siguientes parámetros a estos métodos:
Objeto de filtro que especifica el documento o los documentos que se van a actualizar.
Actualice el documento que especifica las modificaciones. Para ver una lista de los operadores disponibles, consulte Operadores de actualizar en el manual de MongoDB Server.
Los métodos de actualización devuelven un tipo UpdateResult que proporciona información sobre la operación, incluido el número de documentos modificados.
Actualiza uno
Para actualizar una sola instancia de Person que coincida con un filtro, utiliza el método updateOne().
El siguiente ejemplo actualiza el Person denominado "Ada Byron" estableciendo el valor del campo age en 23 y el valor del campo name en "Ada Lovelace":
collection.updateOne( eq("name", "Ada Byron"), combine(set("age", 23), set("name", "Ada Lovelace")) ).subscribe(new OperationSubscriber<>());
Actualiza múltiples
Para actualizar todas las instancias de Person que coincidan con un filtro, usa el método updateMany().
El siguiente ejemplo establece el valor del campo zip en null para todas las instancias de Person que tienen un valor zip no nulo:
collection.updateMany(not(eq("zip", null)), set("zip", null)) .subscribe(new OperationSubscriber<>());
Reemplace uno
Para reemplazar una instancia Person existente por completo, utilice el método replaceOne().
El siguiente ejemplo reemplaza la instancia Person que tiene un valor de campo name de "Ada Lovelace" con el Person al que hace referencia la variable ada:
collection.replaceOne(eq("name", "Ada Lovelace"), ada) .subscribe(new OperationSubscriber<>());
borrar datos
Para borrar documentos de una colección, utilice los métodos deleteOne() y deleteMany(). Pase un objeto filtro para hacer coincidir el o los documentos que desea borrar.
Los métodos de eliminación devuelven un tipo DeleteResult que proporciona información sobre la operación, incluido el número de documentos eliminados.
deleteOne
Para borrar una sola Person que coincida con un filtro, utiliza el método deleteOne().
El siguiente ejemplo elimina una instancia Person que tiene un valor de campo address.city de "Wimborne":
collection.deleteOne(eq("address.city", "Wimborne")) .subscribe(new OperationSubscriber<>());
Borrar múltiples
Para borrar todas las instancias de Person que coincidan con un filtro, utilice el método deleteMany().
El siguiente ejemplo borra todas las instancias de Person que tienen un valor de campo de address.city de "London":
collection.deleteMany(eq("address.city", "London")) .subscribe(new OperationSubscriber<>());
Información Adicional
Para obtener más información sobre las operaciones CRUD mencionadas en esta guía, consulte la sección Operaciones CRUD.
Documentación de la API
Para aprender más sobre los métodos y clases mencionados en esta guía, consulta la siguiente documentación de la API: