POJO CRUD 操作示例
本页内容
本指南使用普通的 Java 对象(POJO),而不是通用的Document
类来建模文档。
本指南中的代码示例来自PojoQuickTour.java 文件在驱动源代码 GitHub 仓库中。
重要
本指南使用自定义 Subscriber
实现,这些实现已在示例自定义 Subscriber 实现 指南中描述。
先决条件
您必须设置以下组件才能运行本指南中的代码示例
MongoDB 服务器在 MongoDB 默认端口(
27017
)上运行在项目中安装了驱动依赖项
以下导入语句
import com.mongodb.client.result.InsertOneResult; import com.mongodb.client.result.InsertManyResult; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoCollection; import com.mongodb.reactivestreams.client.MongoDatabase; import org.bson.codecs.configuration.CodecRegistry; import org.bson.codecs.pojo.PojoCodecProvider; import java.util.List; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Updates.*; import static java.util.Arrays.asList; import static org.bson.codecs.configuration.CodecRegistries.fromProviders; import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; POJO 类定义。从 GitHub 上驱动源代码仓库复制
Person
和Address
POJO 的完整代码
创建自定义 CodecRegistry
在您可以使用POJO与驱动程序一起使用之前,您需要配置CodecRegistry
以包含处理POJOs到和从BSON的编解码器。完成此操作的最简单方法是使用PojoCodecProvider.builder()
方法创建和配置一个CodecProvider
。
以下示例结合了默认编解码器注册表和配置为自动创建POJO Codec
实例的PojoCodecProvider
。
CodecRegistry pojoCodecRegistry = fromRegistries( MongoClientSettings.getDefaultCodecRegistry(), fromProviders(PojoCodecProvider.builder().automatic(true).build()) );
注意
将按顺序检查注册表,直到其中一个返回所需类的编解码器。应将DefaultCodecRegistry
放在列表中第一,而PojoCodecProvider
应始终是最后一个CodecProvider
,因为它几乎可以为任何类提供编解码器。
使用CodecRegistry
以下列表描述了设置pojoCodecRegistry
以使用的方法
在实例化
MongoClient
对象时设置它MongoClientSettings settings = MongoClientSettings.builder() .codecRegistry(pojoCodecRegistry) .build(); MongoClient mongoClient = MongoClients.create(settings); 使用一个替代的
CodecRegistry
与MongoDatabase
database = database.withCodecRegistry(pojoCodecRegistry); 使用一个替代的
CodecRegistry
与MongoCollection
collection = collection.withCodecRegistry(pojoCodecRegistry);
将POJO插入MongoDB
编解码器注册表会自动尝试为未知类创建POJO Codec
。这允许您开箱即用使用POJO,而无需任何额外配置。
在您可以将POJO插入MongoDB之前,创建一个配置了POJO类的MongoCollection
实例。
MongoCollection<Person> collection = database.getCollection("people", Person.class);
插入人员实例
要将人员插入集合中,请使用集合的insertOne()
方法
Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1")); collection.insertOne(ada).subscribe(new OperationSubscriber<InsertOneResult>());
插入多个人员实例
要插入多个Person
实例,可以使用集合的insertMany()
方法,该方法需要一个包含Person
实例的列表作为参数。
以下示例将多个Person
实例添加到集合中
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>());
查询集合
要查询集合,可以使用find()
方法。
以下示例将打印集合中所有的Person
实例
collection.find().subscribe(new PrintToStringSubscriber<>());
Person{id='...', name='Ada Byron', age=20, address=Address{street='St James Square', city='London', zip='W1'}} Person{id='...', name='Charles Babbage', age=45, address=Address{street='5 Devonshire Street', city='London', zip='W11'}} Person{id='...', name='Alan Turing', age=28, address=Address{street='Bletchley Hall', city='Bletchley Park', zip='MK12'}} Person{id='...', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
指定查询过滤器
为了查询符合特定条件的Person
实例,将一个过滤器对象传递给find()
方法。为了便于创建过滤器对象,驱动器提供了Filters
辅助方法。
重要
在查询POJO时,您必须针对文档字段名进行查询,而不是POJO属性名。它们默认相同,但可以更改POJO属性名映射的方式。
获取匹配过滤器的单个人员
以下示例通过传递一个指定等量条件的eq()
过滤器对象来查找数据库中第一个具有address.city
值为Wimborne
的Person
。
collection.find(eq("address.city", "Wimborne")) .first() .subscribe(new PrintToStringSubscriber<>());
Person{id='591dbc2550852fa685b3ad1a', name='Timothy Berners-Lee', age=61, address=Address{street='Colehill', city='Wimborne', zip='null'}}
获取所有匹配过滤器的人员实例
以下示例打印出所有age
值大于30
的文档。
collection.find(gt("age", 30)).subscribe(new PrintToStringSubscriber<>());
更新文档
要更新集合中的文档,您可以使用集合的 updateOne()
和 updateMany()
方法。
将以下参数传递给方法
过滤器对象,用于确定要更新的文档或文档。要指定空过滤器并匹配所有
Person
实例,请使用空的Document
对象。指定要修改的文档的更新文档。要查看可用的操作符列表,请参阅服务器手册中的更新操作符。
更新方法返回一个 UpdateResult
类型,该类型提供了有关操作的信息,包括更新的文档数量。
更新单个人员
要更新单个 Person
,请使用 updateOne()
方法。
以下示例将名为 "Ada Byron"
的 Person
的年龄更新为 23
,并将其姓名更新为 "Ada Lovelace"
。
collection.updateOne( eq("name", "Ada Byron"), combine(set("age", 23), set("name", "Ada Lovelace")) ).subscribe(new OperationSubscriber<>());
更新多个人员实例
要更新所有符合筛选条件的 Person
实例,请使用 updateMany()
方法。
以下示例将所有具有 zip
值的文档的 zip
字段设置为 null
。
collection.updateMany(not(eq("zip", null)), set("zip", null)) .subscribe(new OperationSubscriber<>());
替换单个人员
另一种更改现有 Person
实例的方法是使用 replaceOne()
方法。
以下示例使用前面 insertOne 示例 中引用的 ada
变量替换名为 "Ada Lovelace"
的 Person
。
collection.replaceOne(eq("name", "Ada Lovelace"), ada) .subscribe(new OperationSubscriber<>());
删除文档
要从集合中删除文档,您可以使用集合的 deleteOne()
和 deleteMany()
方法。
传递一个筛选对象以匹配要删除的文档或文档。要指定空筛选,请使用空 Document
对象。
删除方法返回一个 DeleteResult
类型,它提供有关操作的信息,包括删除的文档数量。
删除符合筛选条件的单个人员
要删除与过滤器匹配的单个 Person
,请使用 deleteOne()
方法。
以下示例删除了一个地址城市值为 Wimborne
的 Person
。
collection.deleteOne(eq("address.city", "Wimborne")) .subscribe(new OperationSubscriber<>());
删除与过滤器匹配的所有 Person 实例
要删除与过滤器匹配的多个 Person
实例,请使用 deleteMany()
方法。
以下示例删除了所有地址城市值为 London
的 Person
实例。
collection.deleteMany(eq("address.city", "London")) .subscribe(new OperationSubscriber<>());