MongoDB中的@DBRef指南

2023/05/18

1. 概述

在本教程中,我们将了解Spring Data MongoDB中的@DBRef注解。我们将使用此注解连接MongoDB文档。此外,我们还将看到MongoDB数据库引用的类型并进行比较。

2. MongoDB数据库手动引用

我们讨论的第一种类型称为手动引用。在MongoDB中,每个文档都必须有一个id字段。因此,我们可以依靠使用它并将文档与它连接起来。

使用手动引用时,我们将被引用文档的_id存储在另一个文档中

稍后,当我们从第一个集合中查询数据时,我们可以启动第二个查询来获取引用的文档。

3. Spring Data MongoDB @DBRef注解

DBRef类似于手动引用,因为它们也包含被引用文档的_id。但是,它们在$ref字段中包含引用文档的集合,并且可选地在$db字段中包含其数据库

与手动引用相比,它的优势在于它阐明了我们引用的是哪个集合。

4. 应用程序设置

4.1 依赖

首先,我们需要添加所需的依赖项才能将MongoDB与Spring Boot结合使用。

让我们将spring-boot-starter-data-mongodb添加到我们的pom.xml中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

4.2 配置

现在,我们通过将以下配置添加到application.properties文件来设置连接:

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=person_database

让我们运行应用程序来测试我们是否可以连接到数据库。我们应该在日志中看到类似这样的消息:

Opened connection [connectionId{localValue:2, serverValue:37}] to localhost:27017

这意味着应用程序可以成功连接到MongoDB。

4.3 集合

在MongoDB中,我们使用集合来存储单个文档。它们是关系型数据库中表的对应物

在此示例中,我们将使用三种不同的数据类型:Person、Dog和Cat。我们会将人与他们的宠物联系起来。

首先,我们创建一个名为person_database的数据库,并在其中创建两个名为Dog和Cat的集合。我们将在每个文档中插入一个文档。为简化起见,它们都只有一个属性:宠物的名字。

让我们将此文档插入到Dog集合中:

{
    _id: ObjectID("622112d71f9dac417b84227d"), 
    name: "Max"
}

然后,让我们将此文档插入Cat集合:

{
    _id: ObjectID("622112781f9dac417b84227b"),
    name: "Loki"
}

现在,让我们创建Person集合并向其中插入一个文档:

{
    _id: ObjectId(),
    name: "Bob",
    pets: [
        {
          "$ref": "Cat",
          "$id": "622112781f9dac417b84227b",
          "$db": ""
        },    
        {
          "$ref": "Dog",
          "$id": "622112d71f9dac417b84227d",
          "$db": ""
        }
    ]
}

我们将宠物作为数组提供。数组的元素需要遵循特定的格式才能将它们用作DBRefs。我们需要在$ref属性中提供集合的名称,在这种情况下,它是Cat和Dog。然后,我们包括引用文档的ID。最后,如果我们想引用来自不同数据库的集合,我们可以选择在$db属性中包含一个数据库名称。

5. 使用@DBRef注解

我们可以将之前创建的集合映射到Java类,类似于我们在使用关系数据库时所做的事情

为简化起见,我们不会为Dog和Cat数据类型创建单独的类。相反,我们将使用包含id和name的Pet类:

public class Pet {
    private String id;
    private String name;

    @Override
    public String toString() {
        return "Pet [id=" + id + ", name=" + name + "]";
    }

    // standard getters and setters
}

现在,我们将创建Person类并通过@DBRef注解包含与Pet类的关联:

@Document(collection = "Person")
public class Person {

    @Id
    private String id;

    private String name;

    @DBRef
    private List<Pet> pets;

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", pets=" + pets + "]";
    }

    // standard getters and setters
}

接下来,让我们创建一个简单的Repository来查询数据:

public interface PersonRepository extends MongoRepository<Person, String> {
}

我们将通过创建一个在启动应用程序时执行MongoDB查询的ApplicationRunner来测试所有内容。让我们重写run()方法并添加日志输出,以便我们可以看到Person集合的内容:

@Override
public void run(ApplicationArguments args) throws Exception {
    logger.info("{}", personRepository.findAll());
}

这将生成类似于以下内容的日志输出,因为我们已经重写了实体类中的toString()方法:

dbref.mongodb.cn.tuyucheng.taketoday.DbRefTester : [Person [id=62249c5c7ffe83c50ad12700, name=Bob, pets=[Pet [id=622112781f9dac417b84227b, name=Loki], Pet [id=622112d71f9dac417b84227d, name=Max]]]]

这意味着我们成功读取并连接了来自不同集合的文档。

5.1 引用不同的数据库

@DBRef注解接收两个参数。其中一个是db参数,它可以用于引用其他数据库中的文档

这是可选的,这意味着如果我们不提供此值,应用程序将在同一数据库中查找引用的文档。

在我们的例子中,如果Cat或Dog集合驻留在名为pet_database的不同数据库中,我们需要将注解更改为:@DBRef(db = “pet_database”)。

5.2 延迟加载

注解接收的另一个参数称为lazy。这是一个布尔值,用于确定是否应延迟加载引用的文档

默认情况下,它是false,这意味着当我们查询主实体时,将急切地加载引用实体。如果我们启用此功能,引用的文档将不会被加载,直到它们被首先访问。

6. 总结

在本文中,我们将MongoDB手动引用与Spring Data MongoDB @DBRef进行了比较。我们创建了三个集合并将它们与此注解联系起来。我们创建了一个Spring Boot应用程序来使用MongoRepository查询这些集合并显示相关文档。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章