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. Collections

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

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

让我们用一些数据在数据库中创建集合。 为此,我们可以使用 Mongo Express,但任何其他工具也可以。

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

让我们将此文档插入到 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": ""
        }
    ]
}

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

5. 使用@DBRef注解

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

为简化起见,我们不会为 DogCat 数据类型创建单独的类。 相反,我们将使用包含 ID 和名称的 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() 方法:

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

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

5.1. 引用不同的数据库

@DBRef 注释接受两个参数。 其中之一是 db 参数,可用于引用其他数据库中的文档。

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

在我们的例子中,如果 CatDog 将驻留在名为 pet_database 的不同数据库中,我们需要将注释更改为:@DBRef(db = “pet_database”)

5.2. 延迟加载

注释接受的另一个参数称为 lazy。 这是一个 boolean 值,用于确定是否应该延迟加载引用的文档。

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

6. 结尾

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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐