1. 概述
在这个教程中,我们将探讨Spring Data MongoDB中的@DBRef
注解。我们将使用这个注解来连接MongoDB文档。此外,我们还会介绍MongoDB数据库引用的类型,并进行比较。
2. MongoDB手动数据库引用
首先讨论的是手动引用。在MongoDB中,每个文档都必须有一个_id
字段。因此,我们可以依赖它来连接文档。
当使用手动引用时,我们在另一个文档中存储被引用文档的_id
。
当我们从第一个集合查询数据时,可以发起第二个查询来获取引用的文档。
3. Spring Data MongoDB @DBRef
注解
DBRef
s与手动引用类似,它们也包含引用文档的_id
。然而,它们在$ref
字段中包含引用文档的集合,在$db
字段中可选地包含其数据库。
这种做法的优点是明确了我们引用的是哪个集合。
4. 应用设置
4.1. 依赖
首先,我们需要添加所需的依赖以在Spring Boot中使用MongoDB。
让我们在pom.xml
中添加spring-boot-starter-data-mongodb
:
<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": ""
}
]
}
我们将宠物作为数组提供。数组中的项需要遵循特定格式才能作为DBRef
s使用。我们需要在$ref
属性中提供集合名称,这里分别是Cat
和Dog
。然后,我们包含引用文档的ID。最后,如果希望从不同数据库引用集合,可以在$db
属性中提供数据库名称。
5. 使用@DBRef
注解
我们可以将先前创建的集合映射到Java类,就像在处理关系数据库时一样。
为了简化,我们不会为Dog
和Cat
数据类型创建单独的类。相反,我们将使用一个包含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> {}
我们将通过创建一个ApplicationRunner
来测试一切,当启动应用时执行MongoDB查询。我们将重写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
,用于引用其他数据库中的文档。这是可选的,如果没有提供这个值,应用程序将在同一数据库中查找引用的文档。
在我们的例子中,如果Cat
或Dog
位于名为pet_database
的数据库中,我们需要将注解更改为@DBRef(db = "pet_database")
。
5.2. 懒加载
注解接受的另一个参数是lazy
,这是一个布尔值,决定是否应懒加载引用的文档。默认情况下,它是false
,这意味着当我们查询主实体时,引用将被积极加载。如果启用此功能,引用的文档将直到首次访问时才被加载。
6. 总结
在这篇文章中,我们比较了MongoDB的手动引用与Spring Data MongoDB的@DBRef
。我们创建了三个集合,并使用这个注解连接它们。我们创建了一个Spring Boot应用,使用MongoRepository
查询这些集合,并展示了相关的文档。
如往常一样,示例代码可在GitHub上找到:GitHub。