接着教程一继续讲解:MongoDB Java Driver 快速入门 —— 增删改查/分页操作(一)
本节的文章仿照了官方提供例子,有兴趣的可以看一下,如果你的英文不好,建议还是看我这篇文章吧,反正我也是一个不正经的翻译,哈哈!
GitHub源码:https://github.com/mongodb/mongo-java-driver/blob/master/driver/src/examples/tour/PojoQuickTour.java
快速入门:http://mongodb.github.io/mongo-java-driver/3.5/driver/getting-started/quick-start-pojo/
POJO代表普通Java对象。
以下代码片段来自可以在github上使用驱动程序源的PojoQuickTour.java示例代码。
必要条件
MongoDB使用MongoDB 27017的默认端口在localhost上运行
MongoDB驱动。 有关如何安装MongoDB驱动程序的说明,请点击上一节教程。
以下是引用到的import语句:
import com.mongodb.Block; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; 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的类Person和Address
Person.java
import org.bson.types.ObjectId; /** * The Person Pojo */ 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.id = new ObjectId(); 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; } @Override public String toString() { return "Person{" + "id='" + id + "'" + ", name='" + name + "'" + ", age=" + age + ", address=" + address + "}"; } }
Address.Java
/** * The Address POJO */ public final class Address { private String street; private String city; private String contry; public Address() { } public Address(final String street, final String city, final String contry) { this.street = street; this.city = city; this.contry = contry; } 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 getContry() { return contry; } public void setContry(final String zip) { this.contry = zip; } @Override public String toString() { return "Address{" + "street='" + street + "'" + ", city='" + city + "'" + ", contry='" + contry + "'" + "}"; } }
创建自定义CodecRegistry(解码器)
在您可以使用 POJO 与驱动程序之前,您需要配置 CodecRegistry
以包括从bson
处理到您的 POJO 的解码器。 最简单的方法是使用PojoCodecProvider.builder()
来创建和配置CodecProvider
以下示例将组合默认编解码器注册表,并将PojoCodecProvider
配置为自动创建PojoCodecs
:
CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(), fromProviders(PojoCodecProvider.builder().automatic().build()));
使用CodecRegistry
有多种方法可以设置 pojoCodecRegistry 以供使用
实例化MongoClient对象时配置
MongoClient mongoClient = new MongoClient("localhost", MongoClientOptions.builder().codecRegistry(pojoCodecRegistry).build());
使用MongoDatabase 时配置 CodecRegistry
database = database.withCodecRegistry(pojoCodecRegistry);
使用 MongoCollection 时配置
CodecRegistry
collection = collection.withCodecRegistry(pojoCodecRegistry);
将 POJO 插入到 MongoCollection
CodecRegistry 将自动尝试为未知类创建一个PojoCodec。 这允许您使用POJO开箱即用,无需任何额外的配置。 有关配置PojoCodecs的信息,请参阅Bson POJO页面。
在MongoDB中插入POJO之前,需要配置Pojo类型的MongoCollection实例:
MongoCollection<Person> collection = database.getCollection("people", Person.class);
新增一个 Person 用户
新增一个 Person 插入到 collection 中,可以使用该集合的 insertOne()方法。
Person ada = new Person("安森", 20, new Address("世贸天阶", "北京市", "中国")); collection.insertOne(ada);
新增多个 Person 用户
新增多个 Person 用户到collection中,可以使用该集合到 insertMany()
方法
// 添加多条数据 List<Person> people = asList( new Person("丹妮", 24, new Address("海淀区", "北京市", "中国")), new Person("依儿", 15, new Address("空中花园", "滨海湾", "新加坡")), new Person("苏菲", 23, new Address("江南区", "首尔", null)) ); collection.insertMany(people);
查询所有Collection集合内容
要查询集合,可以使用集合的 find()方法。
以下示例打印集合中的所有Person实例:
Block<Person> printBlock = new Block<Person>() { @Override public void apply(final Person person) { System.out.println(person); } }; collection.find().forEach(printBlock);
该示例使用FindIterable对象上的forEach方法将块应用于每个Person并输出以下内容:
Person{id='59abd12c26e76a045c7f39be', name='安森', age=20, address=Address{street='世贸天阶', city='北京市', contry='中国'}} Person{id='59abd12c26e76a045c7f39bf', name='丹妮', age=24, address=Address{street='海淀区', city='北京市', contry='中国'}} Person{id='59abd12c26e76a045c7f39c0', name='依儿', age=15, address=Address{street='空中花园', city='滨海湾', contry='新加坡'}} Person{id='59abd12c26e76a045c7f39c1', name='苏菲', age=23, address=Address{street='江南区', city='首尔', contry='null'}}
指定 Filter过滤器 查询
要查询符合特定条件的Person实例,请将对象传递给find()方法。 为了方便创建过滤器对象,Java驱动程序提供了 Filters 过滤器帮助。
当查询POJO时,您必须查询数据库document的字段名称,而不是java中的Pojo的属性名称。 默认情况下,它们是相同的,但是可以更改POJO属性名称的映射方式。
根据规则,匹配单个用户
例如,要找到居住在“首尔”第一个人通过一个 eq过滤器对象 来指定相等条件,这里用到了first,只取第一个点意思:
somebody = collection.find(eq("address.city", "首尔")).first();
查询结果如下
查询 city 等于 '首尔' 的对象 Person{id='59abd12c26e76a045c7f39c1', name='苏菲', age=23, address=Address{street='江南区', city='首尔', contry='null'}}
根据规则,匹配所有用户实例
查询年龄大于20岁的用户
collection.find(gt("age", 20)).forEach(printBlock);
更新、替换、删除文档操作
更新可以使用 updateOne 来更新单条数据,也可以使用 updateMany 更新多条数据,更新结果会返回一个UpdateResult对象
同样的删除方法也有 deleteOne 和 deleteMany 方法,删除结果会返回一个DeleteResult对象
替换文档对象用到了replaceOne方法,测试发现只要ObjectId不变,其他Java对象的值可以替换。否则会有id不同的错误出现。
完整Java代码示例
建议测试用Debug方式,看数据库,会更明白
import com.mongodb.Block; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; 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.combine; import static com.mongodb.client.model.Updates.set; import static java.util.Arrays.asList; import static org.bson.codecs.configuration.CodecRegistries.fromProviders; import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; /** * 快速入门官方参考: https://mongodb.github.io/mongo-java-driver/3.5/getting-started-pojo */ public class PojoQuickTour { public static void main(final String[] args) { MongoClient mongoClient; if (args.length == 0) { // 连接到本地数据库服务器 mongoClient = new MongoClient(); } else { mongoClient = new MongoClient(new MongoClientURI(args[0])); } // create codec registry for POJOs(为POJO创建编解码器注册表) CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(), fromProviders(PojoCodecProvider.builder().automatic(true).build())); // 查询 mydb 数据库 MongoDatabase database = mongoClient.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry); // 查询 people 文档(表) MongoCollection<Person> collection = database.getCollection("people", Person.class); // 删除表中的所有数据 collection.drop(); // 添加1条数据 Person ada = new Person("安森", 20, new Address("世贸天阶", "北京市", "中国")); collection.insertOne(ada); // 添加多条数据 List<Person> people = asList( new Person("丹妮", 24, new Address("海淀区", "北京市", "中国")), new Person("依儿", 15, new Address("空中花园", "滨海湾", "新加坡")), new Person("苏菲", 23, new Address("江南区", "首尔", null)) ); collection.insertMany(people); Person somebody = collection.find().first(); System.out.println("查询第一条数据: " + somebody + "\n"); System.out.println("总人数:" + collection.count() + "\n"); // 打印所有数据 Block<Person> printBlock = new Block<Person>() { @Override public void apply(final Person person) { System.out.println(person); } }; collection.find().forEach(printBlock); somebody = collection.find(eq("address.city", "首尔")).first(); System.out.println("\n查询 city 等于 '首尔' 的对象\n" + somebody); System.out.println("\n查询年龄大于20的对象"); collection.find(gt("age", 20)).forEach(printBlock); // 更新一条数据 UpdateResult updateResult = collection.updateOne(eq("name", "安森"), combine(set("age", 23), set("name", "天爱"))); System.out.println("\n更新一条 '安森' 记录, 受影响记录:" + updateResult.getModifiedCount() + "条\n"); // 更新多条country != null的数据为 contry='中华人名共和国' updateResult = collection.updateMany(not(eq("address.contry", null)), set("address.contry", "中华人名共和国")); System.out.println("更新多条country != null的数据为 contry='中华人名共和国',受影响记录:" + updateResult.getModifiedCount() + "条\n"); // 替换数据(需要保证ObjectId不变) updateResult = collection.replaceOne(eq("name", "天爱"), ada); System.out.println("替换一条 '天爱' 数据为 '安森',受影响记录:" + updateResult.getModifiedCount() + "条\n"); // 删除一条 city=首尔 数据 DeleteResult deleteResult = collection.deleteOne(eq("address.city", "首尔")); System.out.println("删除一条 city=首尔 数据,共删除:" + deleteResult.getDeletedCount() + "行\n"); // 删除多条 city=北京市 数据 deleteResult = collection.deleteMany(eq("address.city", "北京市")); System.out.println("删除多条 city=北京市 数据,共删除:" + deleteResult.getDeletedCount() + "行"); // 删除数据库 database.drop(); // 释放连接 mongoClient.close(); } }
输出打印
查询第一条数据: Person{id='59abd12c26e76a045c7f39be', name='安森', age=20, address=Address{street='世贸天阶', city='北京市', contry='中国'}} 总人数:4 Person{id='59abd12c26e76a045c7f39be', name='安森', age=20, address=Address{street='世贸天阶', city='北京市', contry='中国'}} Person{id='59abd12c26e76a045c7f39bf', name='丹妮', age=24, address=Address{street='海淀区', city='北京市', contry='中国'}} Person{id='59abd12c26e76a045c7f39c0', name='依儿', age=15, address=Address{street='空中花园', city='滨海湾', contry='新加坡'}} Person{id='59abd12c26e76a045c7f39c1', name='苏菲', age=23, address=Address{street='江南区', city='首尔', contry='null'}} 查询 city 等于 '首尔' 的对象 Person{id='59abd12c26e76a045c7f39c1', name='苏菲', age=23, address=Address{street='江南区', city='首尔', contry='null'}} 查询年龄大于20的对象 Person{id='59abd12c26e76a045c7f39bf', name='丹妮', age=24, address=Address{street='海淀区', city='北京市', contry='中国'}} Person{id='59abd12c26e76a045c7f39c1', name='苏菲', age=23, address=Address{street='江南区', city='首尔', contry='null'}} 更新一条 '安森' 记录, 受影响记录:1条 更新多条country != null的数据为 contry='中华人名共和国',受影响记录:3条 替换一条 '天爱' 数据为 '安森',受影响记录:1条 删除一条 city=首尔 数据,共删除:1行 删除多条 city=北京市 数据,共删除:2行