MongoDB Java Driver 快速入门 —— Document转换Java类对象(二)

接着教程一继续讲解: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对象

同样的删除方法也有 deleteOnedeleteMany 方法,删除结果会返回一个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行


赞(52) 打赏
未经允许不得转载:优客志 » 数据库
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏