Visão geral
Neste guia, você pode aprender como 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 o artigo Plain Old Java Object na Wikipedia.
O exemplo deste guia demonstra como executar as seguintes tarefas:
Configurar o driver para serializar e desserializar POJOs
Execute operações CRUD que usam dados modelados por POJOs
Exemplo de POJO
As seções deste guia usam a seguinte amostra de classe POJO, que descreve as características das 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; }
@Override public String toString() { return "\nFlower {\n\tid: " + id + "\n\tname: " + name + "\n\tcolors: " + colors + "\n\tisBlooming: " + isBlooming + "\n\theight: " + height + "\n}"; }}Ao definir um POJO para armazenar e recuperar dados dentro do MongoDB, use as seguintes diretrizes:
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 usando as convenções de nomenclatura JavaBean em seu POJO, o driver os chamará ao serializar ou desserializar dados. Se você omitir os métodos de getter ou setter para um campo de propriedade pública, o driver acessará ou atribuirá a eles diretamente.
Configurar o driver para POJOs
Para configurar o driver para usar POJOs, você deve especificar os seguintes componentes:
PojoCodecProviderinstância que tem codecs que definem como codificar e decodificar os dados entre o formato POJO e BSON. O provedor também especifica a quais classes ou pacotes POJO os codecs se aplicam.CodecRegistryinstância que contém os codecs e outras informações relacionadas.MongoDatabaseouMongoCollectioninstância configurada para usar oCodecRegistry.MongoCollectioninstância criada com a classe de documento POJO vinculada ao tipo genéricoTDocument.
Execute as seguintes etapas para atender aos requisitos de configuração definidos na seção anterior:
Configure o
PojoCodecProvider. Neste exemplo, usamos a configuraçãoautomatic(true)dePojoCodecProvider.Builderpara aplicar os codecs a qualquer classe e suas propriedades.CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();Observação
Os fornecedores de codecs também contêm outros objetos, como instâncias
ClassModeleConvention, que definem melhor o comportamento da serialização. Para obter mais informações sobre fornecedores de codecs e personalização, consulte o guia sobre personalização do POJO.Adicione a instância
PojoCodecProvidera umCodecRegistry. OCodecRegistrypermite a você especificar um ou mais fornecedores de codec para codificar os dados POJO. Neste exemplo, chamamos os seguintes métodos:fromRegistries()para combinar múltiplasCodecRegistryinstâncias em uma instânciagetDefaultCodecRegistry()para recuperar uma instância doCodecRegistryde uma lista de fornecedores de codecfromProviders()para criar uma instânciaCodecRegistrya partir doPojoCodecProvider
O seguinte código mostra como instanciar o
CodecRegistry:// Include the following static imports before your class definitionimport 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 a instância do
MongoDatabaseouMongoCollectionpara utilize os codecs noCodecRegistry. Você pode configurar um banco de dados ou collection para especificar os codecs.Neste exemplo, definimos o
CodecRegistryem umMongoDatabasechamadosample_pojosusando o métodowithCodecRegistry():MongoClient mongoClient = MongoClients.create(uri);MongoDatabase database = mongoClient.getDatabase("sample_pojos").withCodecRegistry(pojoCodecRegistry);Passe sua classe POJO para sua chamada para
getCollection()como o parâmetro de classe de documento e especifique-o como o argumento de tipo de sua instânciaMongoCollection, conforme mostrado no código a seguir:MongoCollection<Flower> collection = database.getCollection("flowers", Flower.class);
Realizar operações CRUD
Depois de configurar a instância MongoCollection para usar o Flower POJO, você poderá executar operações CRUD nos dados modelados pelo POJO.
Este exemplo demonstra como realizar as seguintes operações usando o Flower POJO:
Inserir instâncias de
Flowerna collectionflowersAtualizar um documento na collection
Excluir um documento na collection
Encontrar e imprimir todos os documentos na collection
// Insert three Flower instancesFlower 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 documentcollection.updateOne( Filters.lte("height", 22), Updates.addToSet("colors", "pink"));
// Delete a documentcollection.deleteOne(Filters.eq("name", "rose"));
// Return and print all documents in the collectionList<Flower> flowers = new ArrayList<>();collection.find().into(flowers);System.out.println(flowers);O exemplo imprime a seguinte saída:
[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}]Observação
Por padrão, o PojoCodecProvider omite campos em seu POJO que estão configurados para null. Para obter mais informações sobre como especificar esse comportamento, consulte o guia de personalização POJO .
Para obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:
Perguntas frequentes
Esta seção responde a perguntas que podem surgir ao armazenar POJOs no MongoDB.
Preciso especificar um valor de campo de ID sozinho?
Não, o PojoCodecProvider gera automaticamente um ObjectId.
O campo ID pode ser uma chave composta?
Sim. Anote um campo que contém vários valores com @BsonId para usá-lo como a chave composta. O exemplo a seguir define uma classe EntityKey com os campos code e date e, em seguida, a usa como o campo _id em um POJO Entity:
public static class EntityKey {
@BsonCreator public EntityKey(@BsonProperty("code") String code, @BsonProperty("date") Date date) { this.code = code; this.date = date; }
// getters}
public static class Entity {
@BsonId private final EntityKey key;
@BsonCreator public Entity(@BsonProperty("key") EntityKey key) { this.key = key; }
// getters and setters}Posso usar polimorfismo em um acessador POJO?
Sim, usando um discriminador. Para obter mais informações, consulte a seção Discriminadores do guia de personalização do POJO.
Posso misturar setters e getters privados, protegidos e públicos?
Não. O codec POJO nativo pressupõe que getters e setters tenham os mesmos modificadores para cada campo.
Por exemplo, os métodos a seguir lançam uma exceção durante a codificação:
private String getField();public String setField(String x);Como corrigir: "org.bson.codecs.configuration.CodecConfigurationException: Não é possível encontrar um codec para a classe X."?
Essa exceção significa que você deve registrar um codec para a classe , pois não existe nenhum.