如何使用 Spring Data MongoDB 访问 MongoDB 数据库?

Spring Data MongoDB 是 Spring 框架提供的一个访问 MongoDB 数据库的模块,该模块延续了 Spring Data 系列统一的数据库访问风格(通过 Template 的方式与定义 Repository 接口的方式),借助于该模块可以使 MongoDB 的访问变得简单又高效。

本文以一个使用 Maven 管理的 Spring Boot 工程为例,结合本地搭建的 MongoDB(版本为 7.0.7)来演示 Spring Data MongoDB 的使用。

在 Spring Boot 中使用 Spring Data MongoDB,只需要引入一个 spring-boot-starter-data-mongodb 依赖即可,该依赖会自动将 Spring Data MongoDB 及相关依赖一并引入,并已与 Spring Boot 进行了无缝集成。

如下为示例工程所使用的 JDK、Maven、Spring Boot 与 Spring Data MongoDB 的版本:

 

text

复制代码

JDK:Amazon Corretto 17.0.8 Maven:3.9.2 Spring Boot:3.2.4 Spring Data MongoDB:4.2.4

本文将以 User 的增、删、改、查为例来演示 Spring Data MongoDB 的使用。开始前先让我们准备一下测试数据。

1 测试数据准备

使用 MongoShell 连接本地 MongoDB 数据库 mongodb://localhost:27017。然后在 MongoShell 命令行执行如下语句来创建一个测试数据库 test,并在 test 库里创建一个集合 users,最后在 users 集合插入 3 条测试数据。

 

shell

复制代码

use test db.createCollection("users") db.getCollection("users").insertMany( [ { email: "larry@larry.com", name: "Larry", role: "ADMIN", description: "I am Larry", created_at: ISODate("2024-01-01T08:00:00+08:00"), updated_at: ISODate("2023-01-01T08:00:00+08:00"), deleted: false }, { email: "jacky@jacky.com", name: "Jacky", role: "EDITOR", description: "I am Jacky", created_at: ISODate("2024-02-01T08:00:00+08:00"), updated_at: ISODate("2023-02-01T08:00:00+08:00"), deleted: false }, { email: "lucy@lucy.com", name: "Lucy", role: "VIEWER", description: "I am Lucy", created_at: ISODate("2024-03-01T08:00:00+08:00"), updated_at: ISODate("2023-03-01T08:00:00+08:00"), deleted: false } ] )

查询一下,发现 3 条数据均已插入,且自动生成了 ID。

 

shell

复制代码

db.getCollection("users").find({}) [ { _id: ObjectId('6607d1e438537258779f990a'), email: 'larry@larry.com', name: 'Larry', role: 'ADMIN', description: 'I am Larry', created_at: ISODate('2024-01-01T00:00:00.000Z'), updated_at: ISODate('2023-01-01T00:00:00.000Z'), deleted: false }, { _id: ObjectId('6607d1e438537258779f990b'), email: 'jacky@jacky.com', name: 'Jacky', role: 'EDITOR', description: 'I am Jacky', created_at: ISODate('2024-02-01T00:00:00.000Z'), updated_at: ISODate('2023-02-01T00:00:00.000Z'), deleted: false }, { _id: ObjectId('6607d1e438537258779f990c'), email: 'lucy@lucy.com', name: 'Lucy', role: 'VIEWER', description: 'I am Lucy', created_at: ISODate('2024-03-01T00:00:00.000Z'), updated_at: ISODate('2023-03-01T00:00:00.000Z'), deleted: false } ]

测试数据准备好后,下面看一下示例工程的依赖与配置。

2 示例工程依赖与配置

2.1 POM.xml 依赖项

如下为示例工程 spring-data-mongodb-demo 的根目录文件 pom.xml 的内容,可以看到其使用了 spring-boot-starter-parent,并引入了 3 个依赖项:spring-boot-starter-webspring-boot-starter-data-mongodb 和 lombok

 

xml

复制代码

<!-- pom.xml --> <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.4</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>spring-data-mongodb-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

2.2 application.yaml 配置

如下为 application.yaml 文件的内容,可以看到该文件配置了本地 MongoDB 的连接信息,并开启了 MongoDB 查询语句的打印。

 

yaml

复制代码

# src/main/resources/application.yaml spring: data: mongodb: host: localhost port: 27017 database: test logging: level: org.springframework.data.mongodb.core: DEBUG

示例工程依赖和配置准备好后,即可以尝试对 Spring Data MongoDB 进行使用了。

3 开始使用 Spring Data MongoDB

3.1 编写 Model 类

首先需要编写一下 Model 类 User.java,其代码如下:

 

java

复制代码

// src/main/java/com/example/demo/model/User.java package com.example.demo.model; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; import java.util.Date; @Data @Document("users") public class User { @Id private String id; private String email; private String name; private Role role; private String description; @Field("created_at") private Date createdAt; @Field("updated_at") private Date updatedAt; private Boolean deleted; public enum Role { ADMIN, EDITOR, VIEWER } }

可以看到,如上代码在类上使用了 @Document 注解,并指定了对应的 MongoDB 集合为 users;对主键字段使用了 @Id 注解;并对与 MongoDB 集合中命名不一致的属性使用了 @Field 注解指定了实际的字段名。此外还使用 Lombok 的 @Data 注解自动生成了 Setters 和 Getters

3.2 编写 Repository

下面我们为 User Model 创建一个对应的 Repository 接口 UserRepository,并将其扩展 MongoRepository 接口。MongoRepository 接口已内置了常用的增、删、改、查方法,通常来说我们无需自己编写任何方法,使用这些默认方法就满足大多数需求了。但 Spring Data MongoDB 还支持在 Repository 接口中按照约定的命名规则添加自定义查询方法。

 

java

复制代码

// src/main/java/com/example/demo/dao/UserRepository.java package com.example.demo.dao; import com.example.demo.model.User; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; public interface UserRepository extends MongoRepository<User, String> { List<User> findByName(String name); }

可以看到,我们只在 UserRepository 接口增加了一个 findByName 自定义方法。

下面即在 src/test/java 文件夹下针对 UserRepository 编写一个单元测试类来对其提供的增、删、改、查方法进行测试。

 

java

复制代码

// src/test/java/com/example/demo/dao/UserRepositoryTest.java package com.example.demo.dao; import com.example.demo.model.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.Date; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest public class UserRepositoryTest { @Autowired private UserRepository userRepository; @Test public void testCount() { long count = userRepository.count(); assertEquals(3, count); } @Test public void testFindAll() { List<User> users = userRepository.findAll(); assertEquals(3, users.size()); } @Test public void testFindById() { Optional<User> optional = userRepository.findById("6607d1e438537258779f990a"); assertTrue(optional.isPresent()); assertEquals("Larry", optional.get().getName()); } @Test public void testFindByName() { List<User> users = userRepository.findByName("Larry"); assertEquals(1, users.size()); assertEquals("Larry", users.get(0).getName()); } @Test public void testSave() { Date now = new Date(); User user = new User(); user.setEmail("linda@linda.com"); user.setName("Linda"); user.setRole(User.Role.EDITOR); user.setDescription("I am Linda"); user.setCreatedAt(now); user.setUpdatedAt(now); user.setDeleted(false); // save userRepository.save(user); } @Test public void testUpdate() { User user = userRepository.findById("6607d1e438537258779f990a").get(); user.setName("Larry2"); userRepository.save(user); } @Test public void testDelete() { userRepository.deleteById("6607d1e438537258779f990a"); } }

测试发现,包括自定义方法在内的各个增、删、改、查方法均是好用的。

3.3 使用 MongoTemplate

除了通过定义 Repository 接口来对 MongoDB 进行通用的增、删、改、查操作外,我们还可以使用更加灵活的 MongoTemplate 来对 MongoDB 进行操作。

下面即为 MongoTemplate 编写一个单元测试类来对其提供的功能进行简单测试。

 

java

复制代码

// src/test/java/com/example/demo/dao/MongoTemplateTest.java package com.example.demo.dao; import com.example.demo.model.User; import com.mongodb.client.result.UpdateResult; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest public class MongoTemplateTest { @Autowired private MongoTemplate mongoTemplate; @Test public void testFindAll() { List<User> users = mongoTemplate.findAll(User.class); assertFalse(users.isEmpty()); } @Test public void testFindByName() { Query query = new Query(Criteria.where("name").is("Jacky")); User user = mongoTemplate.findOne(query, User.class); assertNotNull(user); assertEquals("jacky@jacky.com", user.getEmail()); } @Test public void testUpdateEmailByName() { Query query = new Query(Criteria.where("name").is("Jacky")); Update update = new Update().set("email", "jacky2@jacky.com"); UpdateResult result = mongoTemplate.updateMulti(query, update, User.class); assertEquals(1, result.getModifiedCount()); } }

可以看到,使用 MongoTemplate 时,我们可以新建一个 Query 对象来拼装任意复杂的查询条件,进而对 MongoDB 进行查询或更新。

综上,本文以示例工程的方式演示了 Spring Data MongoDB 提供的两种 MongoDB 的访问方式(通过定义 Repository 和使用 MongoTemplate),总体来说该模块保持了 Spring Data 系列通用的设计思路与实现模式,使用起来非常的直观简便。完整示例工程已提交至本人 GitHub,欢迎关注或 Fork。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值