Visão geral
Neste guia, você aprenderá a usar o driver Java Reactive Streams para armazenar e recuperar dados modelados por objetos Java antigos simples, ou POJOs. POJOs são frequentemente usados para encapsulamento de dados, que é a prática de separar lógica de negócios da representação de dados.
Dica
Para saber mais sobre POJOs, veja objeto Java antigo no Wikipedia.
Este guia mostra como executar as seguintes tarefas:
Configurar o driver para serializar e desserializar POJOs
Execute operações CRUD usando dados modelados por POJOs
Importante
Este guia usa implementações personalizadas de Subscriber , que são descritas no guia Exemplos de implementações personalizadas de assinantes .
POJOs de amostra
Os exemplos neste guia usam as classes POJO Person e Address para modelar documentos em uma coleção de amostra chamada people.
A classe Person armazena o nome, a idade e o endereço de uma pessoa. Esta classe tem a seguinte definição:
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 + "}"; } }
A classe Address armazena uma rua, cidade e CEP. Esta classe tem a seguinte definição:
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 + "'" + "}"; } }
Ao definir uma classe POJO, certifique-se de atender aos seguintes requisitos:
A classe POJO não pode implementar interfaces ou estender classes de uma framework.
Inclua todos os campos para os quais deseja armazenar e recuperar dados e certifique-se de que não estejam marcados como
staticoutransient.Se você incluir métodos getter ou setter públicos seguindo as convenções de nomenclatura do JavaBean, o driver os chamará ao serializar ou desserializar dados. Se você omitir métodos de getter ou setter para um campo público, o driver acessará ou atribuirá a eles diretamente.
Configurar o driver para POJOs
Antes de usar um POJO com o driver Java Reactive Streams, você deve configurá-lo para serializar e desserializar POJOs criando um CodecRegistry personalizado. As etapas a seguir mostram como criar o CodecRegistry e aplicá-lo a um cliente, banco de dados ou coleção.
Crie um CodecRegistry.
Crie um CodecRegistry que combine o registro de codec padrão com o PojoCodecProvider, conforme mostrado no código a seguir:
CodecRegistry pojoCodecRegistry = fromRegistries( getDefaultCodecRegistry(), fromProviders(pojoCodecProvider) );
Observação
Os registros são verificados em ordem até que um retorne um codec para a classe solicitada. Inclua o registro de codec padrão primeiro na lista e inclua o PojoCodecProvider por último, pois ele pode fornecer um codec para quase qualquer classe.
Aplique o CodecRegistry.
Configure uma instância MongoClient, MongoDatabase ou MongoCollection para usar o CodecRegistry personalizado. Você pode definir o registro do codec de uma das seguintes maneiras:
Defina o
CodecRegistryem umMongoClient:MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(pojoCodecRegistry) .build(); Defina o
CodecRegistryem umMongoDatabase:MongoDatabase database = mongoClient.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry); Defina o
CodecRegistryem umMongoCollection:MongoCollection<org.bson.Document> rawCollection = database.getCollection("people").withCodecRegistry(pojoCodecRegistry);
Obtenha uma coleção digitada.
Passe sua classe POJO para getCollection() como o parâmetro de classe de documento e especifique-o como o argumento de tipo de sua instância MongoCollection , conforme mostrado no código a seguir:
MongoCollection<Person> collection = database.getCollection("people", Person.class);
Realizar operações CRUD
Depois de configurar o driver para usar o POJO Person, você poderá executar operações CRUD nos dados modelados pelo POJO.
Insert Data
O registro do codec cria automaticamente um POJO Codec para classes desconhecidas, permitindo que você use POJOs prontos para uso sem configurações adicionais.
Para inserir um único Person na coleção, chame o método insertOne() e inscreva-se no resultado. O exemplo a seguir insere uma instância Person denominada ada na coleção people:
Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1")); collection.insertOne(ada).subscribe(new OperationSubscriber<InsertOneResult>());
Para inserir várias instâncias Person, chame o método insertMany() e passe uma lista de instâncias, conforme mostrado no exemplo a seguir:
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>());
Dados da consulta
Para consultar a coleção, use o método find(). Você pode passar um objeto de filtro para o método find() para recuperar documentos que correspondem a determinadas condições. O driver fornece métodos assistentes Filters que você pode usar para criar objetos de filtro.
Importante
Ao fazer query em POJOs, você deve fazer query contra o nome do campo do documento e não o nome da propriedade POJO. Eles são os mesmos por padrão, mas é possível alterar a forma como o driver mapeia os nomes das propriedades POJO.
Retrieve One
Para recuperar a primeira instância Person que corresponde a um filtro, chame o método first() no resultado de uma operação find().
O exemplo a seguir recupera a primeira instância Person que tem um 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 vários
Para recuperar todas as instâncias Person que correspondem a um filtro, chame o método find() e inscreva-se nos resultados.
O exemplo a seguir recupera cada instância Person que tem um valor de campo age maior 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'}}
Atualizar dados
Para atualizar documentos em uma coleção, use os métodos updateOne() e updateMany() . Passe os seguintes parâmetros para esses métodos:
Objeto de filtro que especifica o documento ou documentos a serem atualizados.
Atualizardocumento que especifica as modificações. Para exibir uma lista de operadores disponíveis, consulte Operadores de atualização no manual do MongoDB Server .
Os métodos de atualização retornam um tipo de UpdateResult que fornece informações sobre a operação, incluindo o número de documentos modificados.
UpdateOne
Para atualizar uma única instância do Person que corresponde a um filtro, utilize o método updateOne().
O exemplo a seguir atualiza o Person nomeado "Ada Byron" definindo o valor do campo age como 23 e o valor do campo name como "Ada Lovelace":
collection.updateOne( eq("name", "Ada Byron"), combine(set("age", 23), set("name", "Ada Lovelace")) ).subscribe(new OperationSubscriber<>());
Atualizar vários
Para atualizar todas as instâncias do Person que correspondem a um filtro, utilize o método updateMany() .
O exemplo a seguir define o valor do campo zip como null para todas as instâncias Person que têm um valor zip não nulo:
collection.updateMany(not(eq("zip", null)), set("zip", null)) .subscribe(new OperationSubscriber<>());
replaceOne
Para substituir uma instância Person existente inteiramente, use o método replaceOne() .
O exemplo a seguir substitui a instância Person que tem um valor de campo name de "Ada Lovelace" pelo Person referenciado pela variável ada:
collection.replaceOne(eq("name", "Ada Lovelace"), ada) .subscribe(new OperationSubscriber<>());
Excluir dados
Para excluir documentos de uma coleção, use os métodos deleteOne() e deleteMany(). Passe um objeto de filtro para corresponder ao documento ou documentos a serem excluídos.
Os métodos de exclusão retornam um tipo de DeleteResult que fornece informações sobre a operação, incluindo o número de documentos excluídos.
Excluir um
Para excluir um único Person que corresponda a um filtro, use o método deleteOne() .
O exemplo a seguir exclui uma instância Person que tem um valor de campo address.city de "Wimborne":
collection.deleteOne(eq("address.city", "Wimborne")) .subscribe(new OperationSubscriber<>());
Excluir vários
Para excluir todas as instâncias do Person que correspondem a um filtro, utilize o método deleteMany() .
O exemplo a seguir exclui todas as instâncias Person que têm um valor de campo address.city de "London":
collection.deleteMany(eq("address.city", "London")) .subscribe(new OperationSubscriber<>());
Informações adicionais
Para saber mais sobre as operações CRUD mencionadas neste guia, consulte a seção Operações CRUD.
Documentação da API
Para aprender mais sobre os métodos e classe mencionados neste guia, consulte a seguinte documentação da API: