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和AddressPOJO 的完整代码
创建自定义 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与MongoDatabasedatabase = database.withCodecRegistry(pojoCodecRegistry); 使用一个替代的
CodecRegistry与MongoCollectioncollection = 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<>());