Visão geral
Neste guia, você pode aprender como usar o driver Java Reactive Streams para armazenar e recuperar dados modelados por objetos Java antigos, 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 .
Amostra de POJOs
Os exemplos deste guia usam as classes Person e Address POJO para modelar documentos em uma collection de amostra chamada people.
A classe Person armazena o nome, idade e 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 código postal. 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 CodecRegistry um.
Crie um CodecRegistry que combine o registro de codec padrão com o PojoCodecProvider, como mostrado no seguinte código:
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 porque ele pode fornecer um codec para quase qualquer classe.
Aplique o CodecRegistry.
Configure uma instância MongoClient, MongoDatabase ou MongoCollection para utilizar o CodecRegistry personalizado. Você pode definir o registro de 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 da classe do documento e especifique-o como o argumento de tipo da sua instância do MongoCollection, conforme mostrado no código a seguir:
MongoCollection<Person> collection = database.getCollection("people", Person.class);
Realizar operações CRUD
Após configurar o driver para utilizar o Person POJO, você poderá executar operações CRUD em dados modelados pelo POJO.
Insert Data
O registro de codec cria automaticamente um POJO Codec para classes desconhecidas, permitindo que você use POJOs prontos para uso sem configuração extra.
Para inserir um único Person na coleção, chame o método insertOne() e assine o resultado. O exemplo a seguir insere uma instância Person denominada ada na collection 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 fazer query da coleção, use o método find(). Você pode passar um objeto de filtro para o método find() para recuperar documentos que correspondam a determinadas condições. O driver fornece métodos assistente Filters que você pode usar para criar objetos de filtro.
Importante
Ao executar query de POJOs, você deve consultar 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 propriedade 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 seguinte recupera a primeira instância do Person que tem um valor de campo do 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 Person instâncias que correspondem a um filtro, chame o método find() e assine os resultados.
O exemplo a seguir recupera todas as instâncias Person que têm 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, utilize os métodos updateOne() e updateMany(). Passe os seguintes parâmetros para estes 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 Person que corresponda a um filtro, use o método updateOne().
O exemplo a seguir atualiza o Person denominado "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 do Person que têm um valor de zip não nulo:
collection.updateMany(not(eq("zip", null)), set("zip", null)) .subscribe(new OperationSubscriber<>());
replaceOne
Para substituir totalmente uma instância do Person existente, utilize o método replaceOne().
O exemplo seguinte 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 seguinte exclui uma instância do 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 Person que correspondem a um filtro, use o método deleteMany().
O exemplo seguinte exclui todas as Person instâncias do que têm um address.city valor de campo "London" de:
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 saber mais sobre os métodos e classes mencionados neste guia, consulte a seguinte documentação da API: