Overview
En esta guía, aprenderá a almacenar y recuperar datos modelados por objetos Java tradicionales (POJO). Los POJO se utilizan a menudo para la encapsulación de datos, que consiste en separar la lógica de negocio de la representación de los datos.
Tip
Para obtener más información sobre los POJO, consulte el Objeto Java simple y antiguo Artículo de Wikipedia.
El ejemplo de esta guía demuestra cómo realizar las siguientes tareas:
Configurar el controlador para serializar y deserializar POJO
Realizar operaciones CRUD que utilicen datos modelados por POJO
Ejemplo POJO
Las secciones de esta guía utilizan la siguiente clase POJO de ejemplo, que describe las características de las flores:
public class Flower { private ObjectId id; private String name; private List<String> colors; private Boolean isBlooming; private Float height; // public empty constructor needed for retrieving the POJO public Flower() { } public Flower(String name, Boolean isBlooming, Float height, List<String> colors) { this.name = name; this.isBlooming = isBlooming; this.height = height; this.colors = colors; } public ObjectId getId() { return id; } public void setId(ObjectId id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Boolean getIsBlooming() { return isBlooming; } public void setIsBlooming(Boolean isBlooming) { this.isBlooming = isBlooming; } public Float getHeight() { return height; } public void setHeight(Float height) { this.height = height; } public List<String> getColors() { return colors; } public void setColors(List<String> colors) { this.colors = colors; } public String toString() { return "\nFlower {\n\tid: " + id + "\n\tname: " + name + "\n\tcolors: " + colors + "\n\tisBlooming: " + isBlooming + "\n\theight: " + height + "\n}"; } }
Al definir un POJO para almacenar y recuperar datos dentro de MongoDB, utilice las siguientes pautas:
La clase POJO no puede implementar interfaces ni extender clases desde un marco.
Incluya todos los campos para los cuales desea almacenar y recuperar datos y asegúrese de que no estén marcados como
staticotransient.Si incluye métodos getter o setter públicos mediante las convenciones de nomenclatura de JavaBean en su POJO, el controlador los invoca al serializar o deserializar datos. Si omite los métodos getter o setter para un campo de propiedad pública, el controlador accede a ellos o los asigna directamente.
Configurar el controlador para POJO
Para configurar el controlador para utilizar POJO, debe especificar los siguientes componentes:
PojoCodecProviderinstancia que tiene Códecs que definen cómo codificar y decodificar los datos entre el formato POJO y BSON. El proveedor también especifica a qué clases o paquetes POJO se aplican los códecs.CodecRegistryinstancia que contiene los códecs y otra información relacionada.MongoDatabaseo instanciaMongoCollectionque está configurada para utilizarCodecRegistry.MongoCollectioninstancia que se crea con la clase de documento POJO vinculada al tipo genéricoTDocument.
Realice los siguientes pasos para cumplir con los requisitos de configuración definidos en la sección anterior:
Configure
PojoCodecProvider. En este ejemplo, usamos la configuraciónautomatic(true)dePojoCodecProvider.Builderpara aplicar los códecs a cualquier clase y sus propiedades.CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); Nota
Los proveedores de códecs también contienen otros objetos, como
ClassModelConventioninstancias y, que definen con más detalle el comportamiento de la serialización. Para obtener más información sobre los proveedores de códecs y la personalización, consulte la guía sobre personalización de POJO.Agregue la instancia
PojoCodecProvidera unCodecRegistry. ElCodecRegistryle permite especificar uno o más proveedores de códecs para codificar los datos POJO. En este ejemplo, llamamos a los siguientes métodos:fromRegistries()para combinar múltiples instanciasCodecRegistryen una sola instanciagetDefaultCodecRegistry()para recuperar una instanciaCodecRegistryde una lista de proveedores de códecsfromProviders()para crear una instanciaCodecRegistrya partir dePojoCodecProvider
El siguiente código muestra cómo instanciar
CodecRegistry:// Include the following static imports before your class definition import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry; import static org.bson.codecs.configuration.CodecRegistries.fromProviders; import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; ... CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider)); Configure la instancia
MongoDatabaseoMongoCollectionpara usar los códecs enCodecRegistry. Puede configurar una base de datos o una colección para especificar los códecs.En este ejemplo, establecemos
CodecRegistryen unMongoDatabasellamadosample_pojosusando el métodowithCodecRegistry():MongoClient mongoClient = MongoClients.create(uri); MongoDatabase database = mongoClient.getDatabase("sample_pojos").withCodecRegistry(pojoCodecRegistry); Pase su clase POJO a su llamada a
getCollection()como parámetro de clase de documento y especifíquelo como el argumento de tipo de su instanciaMongoCollection, como se muestra en el siguiente código:MongoCollection<Flower> collection = database.getCollection("flowers", Flower.class);
Realizar operaciones CRUD
Una vez que haya configurado la instancia MongoCollection para usar el POJO Flower, puede realizar operaciones CRUD en los datos modelados por el POJO.
Este ejemplo demuestra cómo realizar las siguientes operaciones utilizando el POJO Flower:
Insertar instancias de
Floweren la colecciónflowersActualizar un documento en la colección
Eliminar un documento de la colección
Encuentra e imprime todos los documentos de la colección
// Insert three Flower instances Flower roseFlower = new Flower("rose", false, 25.4f, Arrays.asList(new String[] {"red", "pink"})); Flower daisyFlower = new Flower("daisy", true, 21.1f, Arrays.asList(new String[] {"purple", "white"})); Flower peonyFlower = new Flower("peony", false, 19.2f, Arrays.asList(new String[] {"red", "green"})); collection.insertMany(Arrays.asList(roseFlower, daisyFlower, peonyFlower)); // Update a document collection.updateOne( Filters.lte("height", 22), Updates.addToSet("colors", "pink") ); // Delete a document collection.deleteOne(Filters.eq("name", "rose")); // Return and print all documents in the collection List<Flower> flowers = new ArrayList<>(); collection.find().into(flowers); System.out.println(flowers);
El ejemplo imprime la siguiente salida:
[ Flower { id: 65b178ffa38ac42044ca1573 name: daisy colors: [purple, white, pink] isBlooming: true height: 21.1 }, Flower { id: 65b178ffa38ac42044ca1574 name: peony colors: [red, green] isBlooming: false height: 19.2 }]
Nota
De forma predeterminada,PojoCodecProvider omite los campos del POJO que tienen el null valor. Para obtener más información sobre cómo especificar este comportamiento, consulte la guía de personalización de POJO.
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de API:
Preguntas frecuentes
Esta sección responde preguntas que pueden surgir al almacenar POJO en MongoDB.
¿Tengo que especificar yo mismo un valor de campo ID?
No, el PojoCodecProvider genera automáticamente un ObjectId.
¿Puede el campo ID ser una clave compuesta?
Sí. Para ver un ejemplo de esto, consulte nuestra implementación en Github.
¿Puedo usar polimorfismo en un accesor POJO?
Sí, mediante un discriminador. Para más información, consulte la sección "Discriminadores" de la guía de personalización de POJO.
¿Puedo mezclar establecedores y captadores privados, protegidos y públicos?
No. El códec POJO nativo asume que los captadores y definidores tienen los mismos modificadores para cada campo.
Por ejemplo, los siguientes métodos generan una excepción durante la codificación:
private String getField(); public String setField(String x);
¿Cómo soluciono: "org.bson.codecs.configuration.CodecConfigurationException: No se puede encontrar un códec para la clase X"?
Esta excepción significa que debe registrar un códec para la clase ya que no existe ninguno.