文档数据格式:POJO
在此页面上
Overview
在本指南中,您可以了解如何存储和检索由简单的旧 Java 对象 (POJO) 建模的数据。POJO 通常用于数据封装,这是将业务逻辑与数据表示分开的做法。
提示
要了解有关 POJO 的更多信息,请参阅 简单 Java 对象(POJO)的维基百科文章。
本指南中的示例说明了如何执行以下任务:
配置驱动程序,对 POJO 进行序列化和反序列化
对使用 POJO 建模的数据进行 CRUD 操作
示例 POJO
本指南中的各个部分使用以下示例 POJO 类,它描述了花朵的特征:
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}"; } }
在定义 POJO 以在 MongoDB 中存储和检索数据时,请使用以下准则:
POJO 类不能实现接口或继承框架中的类。
放入您要存储和检索数据的所有字段,并确保它们没有标记为
static
或transient
。如果您按照 JavaBean 命名约定在您的 POJO 中包含了公共 getter 或 setter 方法,驱动程序将在序列化或反序列化数据时调用这些方法。如果您省略了一个公共属性字段的 getter 或 setter 方法,驱动程序将直接访问或赋值给这些字段。
为 POJO 配置驱动程序
要将驱动程序配置为使用 POJO,您必须指定以下组件:
PojoCodecProvider
实例,其拥有的编解码器将定义如何在 POJO 格式和 BSON 之间对数据进行编码和解码。提供者还将指定该编解码器适用于哪些 POJO 类或包。包含编解码器和其他相关信息的
CodecRegistry
实例。配置为使用
CodecRegistry
的MongoDatabase
或MongoCollection
实例。使用绑定到
TDocument
泛型类型的 POJO 文档类创建的MongoCollection
实例。
执行以下步骤以满足上一节中定义的配置要求:
配置
PojoCodecProvider
。在此示例中,我们使用PojoCodecProvider.Builder
的automatic(true)
设置将编解码器应用于任何类及其属性。CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); 注意
编解码器提供商还包含其他对象,例如进一步定义序列化行为的
ClassModel
和Convention
实例。有关编解码器提供商和自定义的更多信息,请参阅POJO 自定义指南。将
PojoCodecProvider
实例添加到CodecRegistry
中。CodecRegistry
允许您指定一个或多个编解码器提供程序来对 POJO 数据进行编码。在本例中,我们调用了以下方法:fromRegistries()
将多个CodecRegistry
实例合并为一个实例getDefaultCodecRegistry()
从编解码器提供商列表中检索CodecRegistry
实例fromProviders()
从PojoCodecProvider
创建一个CodecRegistry
实例
以下代码说明了如何实例化
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)); 配置
MongoDatabase
或MongoCollection
实例以使用CodecRegistry
中的编解码器。您可以配置一个数据库或集合以指定编解码器。在该示例中,我们使用
withCodecRegistry()
方法在名为sample_pojos
的MongoDatabase
上设置了CodecRegistry
。MongoClient mongoClient = MongoClients.create(uri); MongoDatabase database = mongoClient.getDatabase("sample_pojos").withCodecRegistry(pojoCodecRegistry); 将 POJO 类作为文档类参数传递给
getCollection()
调用,并将其指定为MongoCollection
实例的类型参数,如以下代码中所示:MongoCollection<Flower> collection = database.getCollection("flowers", Flower.class);
执行 CRUD 操作
在将 MongoCollection
实例配置为使用 Flower
POJO 后,您可以对 POJO 建模的数据执行 CRUD 操作。
该示例说明了如何使用 Flower
POJO 执行以下操作:
将
Flower
实例插入到flowers
集合中更新集合中的文档
删除集合中的文档
查找并输出集合中的所有文档
// 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);
该示例输出以下内容:
[ 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 }]
注意
默认, PojoCodecProvider
会忽略 POJO 中设置为null
的字段。有关如何指定此行为的更多信息,请参阅POJO 自定义指南。
有关本节中提到的方法和类的详情,请参阅以下 API 文档:
常见问题解答
This section answers questions that may arise when storing POJOs in MongoDB.
我是否必须自己指定 ID 字段值?
不会, PojoCodecProvider
会自动生成 ObjectId。
ID 字段可以是复合键吗?
Yes. For an example of this, see our implementation in Github.
我可以在 POJO 访问器中使用多态性吗?
Yes, by using a discriminator. For more information, see the 鉴别器 section of the POJO Customization guide.
我是否可以混合使用私有、受保护和公共 setter 和 getter?
No. The native POJO codec assumes that getters and setters have the same modifiers for each field.
例如,以下方法会在编码期间引发异常:
private String getField(); public String setField(String x);
如何修复“org.bson.codecs.configuration.CodecConfigurationException:找不到 X 类的编解码器”?
This exception means you must register a codec for the class since none exist.