# SpringBoot集成MongoDB企业级教程
# 1. 开发环境准备
# 1.1 环境清单
| 工具/框架 | 版本号 | 备注 |
|---|---|---|
| IDEA | 2023 Ultimate | 项目管理工具 |
| JDK | 17+ | SpringBoot 3.x强制要求,需配置环境变量 |
| Maven | 3.9.4 | IDEA自带,仅需配置国内镜像源 |
| SpringBoot | 3.5.9 | 核心框架 |
| MongoDB | 7.0.28 | 文档型数据库 |
| MySQL | 8.4.8 | 仅列示,本教程核心为MongoDB |
# 1.2 环境验证
# 1.2.1 JDK验证
打开CMD/终端,执行以下命令,确保输出JDK 17+版本:
java -version
示例输出:java version "17.0.9" 2023-10-17 LTS
# 1.2.2 Maven验证
执行以下命令,确认Maven版本:
mvn -v
示例输出:Apache Maven 3.9.4
# 1.2.3 MongoDB连接验证
使用提供的连接信息测试MongoDB连通性,执行命令:
mongosh "mongodb://localhost:27017" -u admin -p MongoDB@hep.cc798 --authenticationDatabase admin
若进入MongoDB交互界面(显示test>),说明连接成功。
# 2. 基于IDEA创建SpringBoot项目

# 3. 企业级项目结构规划
# 3.1 基础包结构
生成项目后,在cc.hep下创建以下子包,符合企业级分层规范:
cc.hep
├── config # 配置类(MongoDB、全局配置等)
├── controller # 控制层(REST接口)
├── entity # 实体类(映射MongoDB文档)
├── exception # 异常处理(全局异常、自定义异常)
├── repository # 数据访问层(操作MongoDB)
├── service # 业务逻辑层(接口+实现)
│ └── impl # 业务层实现类
├── utils # 工具类(通用返回、常量等)
└── SpringBootMongoDbApplication.java # 启动类
2
3
4
5
6
7
8
9
10
# 3.2 各包职责说明
config:存放MongoDB自定义配置、Web配置等;entity:对应MongoDB的集合(Collection),每个类映射一个文档;repository:继承Spring Data MongoDB的Repository接口,封装数据库操作;service:封装业务逻辑,调用repository层;controller:对外提供REST接口,接收请求并调用service;exception:统一处理项目中的异常,返回友好提示;utils:封装通用工具,如返回结果类、常量等。
# 4. MongoDB核心配置
# 4.1 确认pom.xml依赖
SpringBoot 3.5.9的pom.xml核心依赖如下(IDEA已自动生成,可核对):
<?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.5.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.hep</groupId>
<artifactId>springboot-mongodb</artifactId>
<version>1.0.0</version>
<name>SpringBoot-MongoDB</name>
<description>SpringBoot集成MongoDB企业级教程</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests> <!-- 新增这行 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 4.2 application.yml配置MongoDB连接
删除默认的application.properties,新建application.yml(更易读的配置格式),添加MongoDB连接配置:
spring:
# MongoDB配置
data:
mongodb:
# 连接地址:格式为 mongodb://用户名:密码@地址:端口/认证数据库?参数
uri: mongodb://admin:MongoDBhep798@localhost:27017/admin?authSource=admin
# 可选:指定默认操作的数据库(若不指定,默认使用admin)
database: test_db
# 连接池配置(企业级优化)
pool:
max-size: 100 # 最大连接数
min-size: 10 # 最小空闲连接数
max-wait-time: 3000 # 最大等待时间(毫秒)
max-life-time: 3600000 # 连接最大存活时间(毫秒)
# 服务端口配置
server:
port: 8080
servlet:
context-path: /api # 接口前缀
# 日志配置(企业级)
logging:
level:
cc.hep.springbootmongodb: DEBUG # 自定义包日志级别
org.springframework.data.mongodb: INFO # MongoDB操作日志级别
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 4.3 MongoDB自定义配置类(企业级优化)
在config包下创建MongoDBConfig.java,自定义MongoTemplate(可选,用于复杂查询优化):
package cc.hep.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
/**
* MongoDB自定义配置类
*/
@Configuration
// 指定repository包路径,关联自定义mongoTemplate(保留,确保Repository使用自定义配置)
@EnableMongoRepositories(
basePackages = "cc.hep.repository",
mongoTemplateRef = "mongoTemplate"
)
public class MongoDBConfig {
/**
* 自定义MongoTemplate Bean(保留核心配置,移除转换器)
*/
@Bean(name = "mongoTemplate")
public MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoMappingContext context) {
MappingMongoConverter converter = new MappingMongoConverter(factory, context);
// 保留原有核心配置:兼容字段名驼峰/下划线映射(createTime ↔ create_time)
converter.setMapKeyDotReplacement("_");
// 保留:禁用冗余的_class字段
converter.setTypeMapper(null);
return new MongoTemplate(factory, converter);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 5. 核心业务代码实现
以「用户管理」为例,实现完整的增删改查(CRUD)功能,符合企业级规范。
# 5.1 实体类(Entity)编写
在entity包下创建User.java,映射MongoDB的user集合:
package cc.hep.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.io.Serializable;
import java.util.Date;
/**
* 用户实体类
* 映射MongoDB的user集合
*/
@Data // 生成getter/setter/toString等
@NoArgsConstructor // 无参构造
@AllArgsConstructor // 全参构造
@Document(collection = "user") // 指定映射的集合名
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id // 映射MongoDB的_id字段(主键)
private String id;
@Field("username") // 映射集合中的username字段(可省略,默认字段名一致)
@Indexed(unique = true) // 创建唯一索引,确保用户名不重复
private String username;
@Field("password")
private String password;
@Field("nickname")
private String nickname;
@Field("age")
private Integer age;
@Field("email")
private String email;
@Field("create_time")
private Date createTime; // 改为Date
@Field("update_time")
private Date updateTime; // 改为Date
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 5.2 数据访问层(Repository)
在repository包下创建UserRepository.java,继承MongoRepository(Spring Data提供的通用CRUD接口):
package cc.hep.repository;
import cc.hep.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* 用户数据访问层
* MongoRepository<实体类, 主键类型> 提供了通用的CRUD方法
*/
@Repository
public interface UserRepository extends MongoRepository<User, String> {
/**
* 根据用户名查询用户(自定义查询方法)
* Spring Data MongoDB会自动根据方法名生成查询语句
* @param username 用户名
* @return 可选的User对象
*/
Optional<User> findByUsername(String username);
/**
* 根据年龄范围查询用户(分页)
* 使用@Query自定义MongoDB查询语句
* @param minAge 最小年龄
* @param maxAge 最大年龄
* @param pageable 分页参数
* @return 分页的User列表
*/
@Query("{'age': {$gte: ?0, $lte: ?1}}")
Page<User> findByAgeBetween(Integer minAge, Integer maxAge, Pageable pageable);
/**
* 根据用户名删除用户(自定义删除方法)
* @param username 用户名
* @return 删除的记录数
*/
long deleteByUsername(String username);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 5.3 通用返回结果封装(工具类)
在utils包下创建Result.java,统一接口返回格式:
package cc.hep.utils;
import lombok.Data;
/**
* 通用返回结果类
* 企业级接口统一返回格式
*/
@Data
public class Result<T> {
// 响应码(200成功,500失败,400参数错误等)
private Integer code;
// 响应消息
private String msg;
// 响应数据
private T data;
// 成功(无数据)
public static <T> Result<T> success() {
return new Result<>(200, "操作成功", null);
}
// 成功(有数据)
public static <T> Result<T> success(T data) {
return new Result<>(200, "操作成功", data);
}
// 失败
public static <T> Result<T> fail(String msg) {
return new Result<>(500, msg, null);
}
// 参数错误
public static <T> Result<T> badRequest(String msg) {
return new Result<>(400, msg, null);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 5.4 业务逻辑层(Service)
# 5.4.1 服务接口
在service包下创建UserService.java:
package cc.hep.service;
import cc.hep.entity.User;
import org.springframework.data.domain.Page;
import java.util.List;
/**
* 用户业务层接口
*/
public interface UserService {
/**
* 新增用户
* @param user 用户对象
* @return 新增的用户
*/
User saveUser(User user);
/**
* 根据ID查询用户
* @param id 用户ID
* @return 用户对象
*/
User getUserById(String id);
/**
* 根据用户名查询用户
* @param username 用户名
* @return 用户对象
*/
User getUserByUsername(String username);
/**
* 查询所有用户
* @return 用户列表
*/
List<User> getAllUsers();
/**
* 分页查询用户
* @param pageNum 页码(从0开始)
* @param pageSize 每页条数
* @return 分页用户列表
*/
Page<User> getUsersByPage(Integer pageNum, Integer pageSize);
/**
* 根据年龄范围分页查询用户
* @param minAge 最小年龄
* @param maxAge 最大年龄
* @param pageNum 页码
* @param pageSize 每页条数
* @return 分页用户列表
*/
Page<User> getUsersByAgeRange(Integer minAge, Integer maxAge, Integer pageNum, Integer pageSize);
/**
* 更新用户
* @param user 用户对象
* @return 更新后的用户
*/
User updateUser(User user);
/**
* 根据ID删除用户
* @param id 用户ID
*/
void deleteUserById(String id);
/**
* 根据用户名删除用户
* @param username 用户名
* @return 删除的记录数
*/
long deleteUserByUsername(String username);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 5.4.2 服务实现类
在service/impl包下创建UserServiceImpl.java:
package cc.hep.service.impl;
import cc.hep.entity.User;
import cc.hep.repository.UserRepository;
import cc.hep.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* 用户业务层实现类
*/
@Service
@RequiredArgsConstructor // Lombok生成构造方法,注入依赖
public class UserServiceImpl implements UserService {
// 注入UserRepository
private final UserRepository userRepository;
@Override
public User saveUser(User user) {
// 设置创建/更新时间(改用Date类型)
user.setCreateTime(new Date()); // 替换 LocalDateTime.now()
user.setUpdateTime(new Date());
// 保存用户
return userRepository.save(user);
}
@Override
public User getUserById(String id) {
Optional<User> userOptional = userRepository.findById(id);
// 若不存在则抛出异常(后续全局异常处理)
return userOptional.orElseThrow(() -> new RuntimeException("用户不存在"));
}
@Override
public User getUserByUsername(String username) {
Optional<User> userOptional = userRepository.findByUsername(username);
return userOptional.orElseThrow(() -> new RuntimeException("用户不存在"));
}
@Override
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Override
public Page<User> getUsersByPage(Integer pageNum, Integer pageSize) {
// 分页+按创建时间降序排序(字段名保持createTime,和实体类一致)
Pageable pageable = PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "createTime"));
return userRepository.findAll(pageable);
}
@Override
public Page<User> getUsersByAgeRange(Integer minAge, Integer maxAge, Integer pageNum, Integer pageSize) {
Pageable pageable = PageRequest.of(pageNum, pageSize);
return userRepository.findByAgeBetween(minAge, maxAge, pageable);
}
@Override
public User updateUser(User user) {
// 先查询用户是否存在
User existUser = getUserById(user.getId());
// 更新字段(仅更新非空字段,企业级规范)
if (user.getNickname() != null) {
existUser.setNickname(user.getNickname());
}
if (user.getAge() != null) {
existUser.setAge(user.getAge());
}
if (user.getEmail() != null) {
existUser.setEmail(user.getEmail());
}
if (user.getPassword() != null) {
existUser.setPassword(user.getPassword());
}
// 更新时间(改用Date类型)
existUser.setUpdateTime(new Date()); // 替换 LocalDateTime.now()
// 保存更新
return userRepository.save(existUser);
}
@Override
public void deleteUserById(String id) {
// 先查询是否存在
getUserById(id);
// 删除
userRepository.deleteById(id);
}
@Override
public long deleteUserByUsername(String username) {
return userRepository.deleteByUsername(username);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# 5.5 全局异常处理
在exception包下创建GlobalExceptionHandler.java,统一处理项目异常:
package cc.hep.exception;
import cc.hep.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理类
* 捕获项目中所有异常,返回统一格式
*/
@Slf4j
@RestControllerAdvice // 全局控制器异常处理
public class GlobalExceptionHandler {
/**
* 处理自定义业务异常
* @param e 运行时异常
* @return 统一返回结果
*/
@ExceptionHandler(RuntimeException.class)
public Result<?> handleRuntimeException(RuntimeException e) {
log.error("业务异常:", e);
return Result.fail(e.getMessage());
}
/**
* 处理MongoDB唯一索引冲突异常(如用户名重复)
* @param e 重复键异常
* @return 统一返回结果
*/
@ExceptionHandler(DuplicateKeyException.class)
public Result<?> handleDuplicateKeyException(DuplicateKeyException e) {
log.error("唯一索引冲突:", e);
return Result.fail("数据已存在,无法重复添加");
}
/**
* 处理参数校验异常
* @param e 参数校验异常
* @return 统一返回结果
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
StringBuilder sb = new StringBuilder();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(";");
}
String msg = sb.toString().substring(0, sb.length() - 1);
log.error("参数校验异常:{}", msg);
return Result.badRequest(msg);
}
/**
* 处理所有未捕获的异常
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(Exception.class)
public Result<?> handleException(Exception e) {
log.error("系统异常:", e);
return Result.fail("系统内部错误,请联系管理员");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 5.6 控制层(Controller)
在controller包下创建UserController.java,提供REST接口:
package cc.hep.controller;
import cc.hep.entity.User;
import cc.hep.service.UserService;
import cc.hep.utils.Result;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户控制层
* 提供用户相关的REST接口
*/
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
/**
* 新增用户
* @param user 用户对象(参数校验)
* @return 新增的用户
*/
@PostMapping("/save")
public Result<User> saveUser(@Valid @RequestBody User user) {
User savedUser = userService.saveUser(user);
return Result.success(savedUser);
}
/**
* 根据ID查询用户
* @param id 用户ID
* @return 用户对象
*/
@GetMapping("/get/{id}")
public Result<User> getUserById(@PathVariable String id) {
User user = userService.getUserById(id);
return Result.success(user);
}
/**
* 根据用户名查询用户
* @param username 用户名
* @return 用户对象
*/
@GetMapping("/getByUsername")
public Result<User> getUserByUsername(@RequestParam String username) {
User user = userService.getUserByUsername(username);
return Result.success(user);
}
/**
* 查询所有用户
* @return 用户列表
*/
@GetMapping("/getAll")
public Result<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return Result.success(users);
}
/**
* 分页查询用户
* @param pageNum 页码(默认0)
* @param pageSize 每页条数(默认10)
* @return 分页用户列表
*/
@GetMapping("/page")
public Result<Page<User>> getUsersByPage(
@RequestParam(defaultValue = "0") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
Page<User> page = userService.getUsersByPage(pageNum, pageSize);
return Result.success(page);
}
/**
* 根据年龄范围分页查询用户
* @param minAge 最小年龄
* @param maxAge 最大年龄
* @param pageNum 页码
* @param pageSize 每页条数
* @return 分页用户列表
*/
@GetMapping("/pageByAge")
public Result<Page<User>> getUsersByAgeRange(
@RequestParam Integer minAge,
@RequestParam Integer maxAge,
@RequestParam(defaultValue = "0") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
Page<User> page = userService.getUsersByAgeRange(minAge, maxAge, pageNum, pageSize);
return Result.success(page);
}
/**
* 更新用户
* @param user 用户对象
* @return 更新后的用户
*/
@PutMapping("/update")
public Result<User> updateUser(@RequestBody User user) {
User updatedUser = userService.updateUser(user);
return Result.success(updatedUser);
}
/**
* 根据ID删除用户
* @param id 用户ID
* @return 操作结果
*/
@DeleteMapping("/delete/{id}")
public Result<?> deleteUserById(@PathVariable String id) {
userService.deleteUserById(id);
return Result.success();
}
/**
* 根据用户名删除用户
* @param username 用户名
* @return 操作结果
*/
@DeleteMapping("/deleteByUsername")
public Result<?> deleteUserByUsername(@RequestParam String username) {
long count = userService.deleteUserByUsername(username);
return Result.success("删除成功,共删除" + count + "条记录");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# 6. 功能测试
# 6.1 启动项目
- 找到项目启动类
SpringBootMongoDbApplication.java:
package cc.hep;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootMongoDbApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMongoDbApplication.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
- 点击启动类右侧的
Run按钮,IDEA会启动SpringBoot项目,控制台输出Started SpringBootMongoDbApplication in xxx seconds表示启动成功。
# 6.2 接口测试(Postman示例)
使用Postman/ApiPost等工具测试接口,以下是核心接口测试示例:
# 6.2.1 新增用户
- 请求地址:
http://localhost:8080/api/user/save - 请求方式:POST
- 请求体(JSON):
{
"username": "test_user",
"password": "123456",
"nickname": "测试用户",
"age": 25,
"email": "test@hep.cc"
}
2
3
4
5
6
7
- 响应结果:
{
"code": 200,
"msg": "操作成功",
"data": {
"id": "65f8a7b2c9d8e7f8a7b2c9d8",
"username": "test_user",
"password": "123456",
"nickname": "测试用户",
"age": 25,
"email": "test@hep.cc",
"createTime": "2026-01-23T10:00:00",
"updateTime": "2026-01-23T10:00:00"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 6.2.2 根据ID查询用户
- 请求地址:
http://localhost:8080/api/user/get/65f8a7b2c9d8e7f8a7b2c9d8 - 请求方式:GET
- 响应结果:与新增用户的data一致
# 6.2.3 分页查询用户
- 请求地址:
http://localhost:8080/api/user/page?pageNum=0&pageSize=5 - 请求方式:GET
- 响应结果:
{
"code": 200,
"msg": "操作成功",
"data": {
"content": [
{
"id": "65f8a7b2c9d8e7f8a7b2c9d8",
"username": "test_user",
"password": "123456",
"nickname": "测试用户",
"age": 25,
"email": "test@hep.cc",
"createTime": "2026-01-23T10:00:00",
"updateTime": "2026-01-23T10:00:00"
}
],
"pageable": {
"pageNumber": 0,
"pageSize": 5,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"offset": 0,
"paged": true,
"unpaged": false
},
"totalElements": 1,
"totalPages": 1,
"last": true,
"size": 5,
"number": 0,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"numberOfElements": 1,
"first": true,
"empty": false
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 7. 企业级优化与最佳实践
# 7.1 MongoDB索引优化
- 为高频查询字段创建索引(如username、age),可通过MongoDB客户端执行:
# 为username创建唯一索引
db.user.createIndex({username: 1}, {unique: true})
# 为age创建普通索引
db.user.createIndex({age: 1})
# 为createTime创建降序索引
db.user.createIndex({createTime: -1})
2
3
4
5
6
- 避免全表扫描,所有查询尽量命中索引。
# 7.2 连接池配置优化
在application.yml中已配置连接池核心参数,可根据业务压力调整:
max-size:最大连接数(建议不超过100);min-size:最小空闲连接数(建议10-20);max-wait-time:连接等待超时(建议3-5秒)。
# 7.3 分页查询最佳实践
- 使用
Pageable+Page实现分页,避免一次性查询大量数据; - 分页时指定排序字段,确保分页结果稳定;
- 大数据量分页时,使用
_id游标分页替代offset分页,提升性能。
# 7.4 事务支持(MongoDB 4.0+)
MongoDB 4.0及以上支持事务,SpringBoot中使用@Transactional注解即可:
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
// 开启MongoDB事务
@Transactional
public void batchSaveUsers(List<User> users) {
users.forEach(user -> {
user.setCreateTime(LocalDateTime.now());
user.setUpdateTime(LocalDateTime.now());
userRepository.save(user);
});
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 7.5 性能监控
- 集成Spring Boot Actuator监控MongoDB连接池、查询性能:
<!-- 添加Actuator依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2
3
4
5
- 配置Actuator暴露监控端点:
management:
endpoints:
web:
exposure:
include: mongodb,health,metrics
2
3
4
5
# 总结
- SpringBoot 3.5.9集成MongoDB的核心是引入
spring-boot-starter-data-mongodb依赖,通过application.yml配置连接信息; - 企业级项目需遵循分层架构(Controller→Service→Repository),封装通用返回结果和全局异常处理;
- Spring Data MongoDB提供了
MongoRepository接口,可简化CRUD操作,也支持自定义查询语句和分页; - 生产环境需优化MongoDB索引、连接池配置,确保性能和稳定性。
本教程从零搭建了符合企业级规范的SpringBoot-MongoDB项目,覆盖了配置、编码、测试、优化全流程,你可直接复制代码使用,也可根据实际业务扩展功能(如文件存储、复杂查询等)。