欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Spring Boot 整合 MongoDB 学习笔记 (新手入门)

Spring Boot 整合 MongoDB 学习笔记 (新手入门)

2025/4/12 16:53:25 来源:https://blog.csdn.net/m0_63949203/article/details/147110862  浏览:    关键词:Spring Boot 整合 MongoDB 学习笔记 (新手入门)

Spring Boot 整合 MongoDB 学习笔记 (新手入门)

目录

  1. 引言
  2. 环境准备
  3. 步骤 1: 添加 Maven/Gradle 依赖
  4. 步骤 2: 配置 MongoDB 连接
  5. 步骤 3: 创建实体类 (Domain Model)
  6. 步骤 4: 创建 Repository 接口
  7. 步骤 5: 实现基础 CRUD 操作
    • 创建 (Create) / 更新 (Update)
    • 读取 (Read)
    • 删除 (Delete)
  8. 步骤 6: 进阶查询 - 使用 MongoTemplate
    • 什么是 MongoTemplate?
    • 使用 QueryCriteria
      • 什么是 Query?
      • 什么是 Criteria?
      • 常用 Criteria 方法
      • 代码示例
    • 使用 Aggregation
      • 什么是 Aggregation?
      • 常用聚合阶段 (Stages)
      • 代码示例
  9. MongoDB 操作与 SQL (MySQL) 对比
  10. 重点内容总结
  11. 结语

1. 引言

本笔记旨在帮助初学者理解如何在 Spring Boot 项目中集成和使用 MongoDB 数据库。我们将从最基础的配置开始,逐步深入到常用的增删改查 (CRUD) 操作,以及更复杂的查询方式,如使用 Query, CriteriaAggregationSpring Data MongoDB 极大地简化了 Java 应用与 MongoDB 的交互。


2. 环境准备

  • JDK: 确保已安装 Java 开发工具包 (推荐 JDK 8 或更高版本)。
  • Maven 或 Gradle: Spring Boot 项目构建工具。
  • IDE: 如 IntelliJ IDEA, Eclipse, VS Code 等。
  • MongoDB: 需要一个正在运行的 MongoDB 实例 (可以是本地安装,也可以是 Docker 容器,或者是云服务如 MongoDB Atlas)。

3. 步骤 1: 添加 Maven/Gradle 依赖

要在 Spring Boot 项目中使用 MongoDB,首先需要添加 spring-boot-starter-data-mongodb 依赖。

Maven (pom.xml):

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><!-- 通常不需要指定版本,Spring Boot会管理 -->
</dependency>

Gradle (build.gradle):

dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'// 其他依赖...
}

注释: 这个 Starter 会自动引入 Spring Data MongoDB 以及所需的 MongoDB Java 驱动程序。


4. 步骤 2: 配置 MongoDB 连接

src/main/resources 目录下的 application.propertiesapplication.yml 文件中配置 MongoDB 的连接信息。

application.properties 格式:

# MongoDB 连接 URI (推荐方式,包含了所有信息)
# 格式: mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[database][?options]]
spring.data.mongodb.uri=mongodb://localhost:27017/mydatabase# 或者分开配置 (如果不用URI)
# spring.data.mongodb.host=localhost
# spring.data.mongodb.port=27017
# spring.data.mongodb.database=mydatabase
# 如果有认证
# spring.data.mongodb.username=your_username
# spring.data.mongodb.password=your_password
# spring.data.mongodb.authentication-database=admin # 通常是 admin 或你的数据库名

application.yml 格式:

spring:data:mongodb:# URI 方式 (推荐)uri: mongodb://localhost:27017/mydatabase# 分开配置方式# host: localhost# port: 27017# database: mydatabase# username: your_username# password: your_password# authentication-database: admin

重点:

  • spring.data.mongodb.uri 是最常用且推荐的配置方式,简洁明了。
  • mydatabase 是你要连接的数据库名称,如果不存在,MongoDB 通常会在第一次写入数据时自动创建。
  • 确保主机名 (localhost) 和端口 (27017 是默认端口) 正确。
  • 如果 MongoDB 设置了用户认证,务必提供 usernamepassword

5. 步骤 3: 创建实体类 (Domain Model)

实体类是 Java 对象,用于映射 MongoDB 中的文档 (Document)。

package com.example.yourproject.model;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;/*** 用户实体类,映射到 MongoDB 中的 "users" 集合。*/
@Document(collection = "users") // 指定映射的 MongoDB 集合名称,如果省略,默认为类名的小写形式 (user)
public class User {@Id // 标记这个字段作为文档的主键 (_id)private String id; // MongoDB 的 _id 通常是 ObjectId 类型,但映射为 String 更方便@Field("user_name") // 可选:如果 Java 字段名与 MongoDB 字段名不同,用 @Field 指定private String name;private int age;private String email;@Field("created_at") // 示例:指定字段名private Date createdAt;// Standard Constructors, Getters, Setters, toString() ...public User() {this.createdAt = new Date(); // 可以在构造函数中设置默认值}public User(String name, int age, String email) {this(); // 调用默认构造函数设置 createdAtthis.name = name;this.age = age;this.email = email;}// --- Getters and Setters ---public String getId() { return id; }public void setId(String id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public Date getCreatedAt() { return createdAt; }public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; }@Overridepublic String toString() {return "User{" +"id='" + id + '\'' +", name='" + name + '\'' +", age=" + age +", email='" + email + '\'' +", createdAt=" + createdAt +'}';}
}

重点:

  • @Document: 标记这是一个映射到 MongoDB 文档的类。collection 属性指定了集合名称。
  • @Id: 标记主键字段,对应 MongoDB 中的 _id。Spring Data MongoDB 会自动处理 String 类型和 MongoDB ObjectId 之间的转换。如果字段名为 id@Id 注解甚至可以省略(但不推荐省略以保证清晰)。
  • @Field: 当 Java 字段名和 MongoDB 文档中的字段名不一致时使用。如果一致,则可以省略。

6. 步骤 4: 创建 Repository 接口

Spring Data MongoDB 提供了一个 MongoRepository 接口,它内置了许多标准的 CRUD 操作方法。我们只需要定义一个接口继承它即可。

package com.example.yourproject.repository;import com.example.yourproject.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** User 数据访问层接口* 继承 MongoRepository<实体类类型, 主键类型>*/
@Repository // 标记这是一个 Spring管理的 Repository Bean
public interface UserRepository extends MongoRepository<User, String> {// Spring Data MongoDB 会根据方法名自动生成查询实现!// 例如:根据 name 查找用户List<User> findByName(String name);// 例如:根据 email 查找单个用户 (假设 email 是唯一的)User findByEmail(String email);// 例如:查找年龄大于某个值的用户List<User> findByAgeGreaterThan(int age);// 更多查询方法可以参照 Spring Data JPA 的命名规范// https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.query-methods.query-creation
}

重点:

  • 继承 MongoRepository<User, String>,其中 User 是实体类,String 是主键 id 的类型。
  • @Repository 注解使得 Spring Boot 能自动扫描并创建这个 Bean。
  • 最强大的功能之一:通过定义符合特定命名规范的方法(如 findByName, findByAgeGreaterThan),Spring Data MongoDB 会自动为你实现这些查询,无需编写任何具体代码!这被称为方法名衍生查询 (Query Methods)

7. 步骤 5: 实现基础 CRUD 操作

现在可以在你的 Service 或 Controller 中注入 UserRepository,并调用其方法进行 CRUD 操作。

package com.example.yourproject.service;import com.example.yourproject.model.User;
import com.example.yourproject.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Optional;@Service
public class UserService {@Autowired // 自动注入 UserRepository 的实例private UserRepository userRepository;/*** 创建或更新用户* 如果 user 对象有 id 且数据库中存在该 id,则执行更新操作。* 如果 user 对象没有 id 或 id 在数据库中不存在,则执行插入操作。*/public User saveOrUpdateUser(User user) {// save() 方法兼具插入和更新功能 (upsert)User savedUser = userRepository.save(user);System.out.println("Saved/Updated User: " + savedUser);return savedUser;}/*** 根据 ID 查找用户*/public Optional<User> findUserById(String id) {// findById 返回一个 Optional<User>,可以更好地处理空结果Optional<User> userOptional = userRepository.findById(id);if (userOptional.isPresent()) {System.out.println("Found User by ID " + id + ": " + userOptional.get());} else {System.out.println("User with ID " + id + " not found.");}return userOptional;}/*** 查找所有用户*/public List<User> findAllUsers() {List<User> users = userRepository.findAll();System.out.println("Found all users: Count = " + users.size());return users;}/*** 使用方法名衍生查询:根据姓名查找用户*/public List<User> findUsersByName(String name) {List<User> users = userRepository.findByName(name);System.out.println("Found users by name '" + name + "': " + users);return users;}/*** 根据 ID 删除用户*/public void deleteUserById(String id) {// 先检查是否存在 (可选,但更安全)if (userRepository.existsById(id)) {userRepository.deleteById(id);System.out.println("Deleted User with ID: " + id);} else {System.out.println("User with ID " + id + " not found, cannot delete.");}}/*** 删除指定用户对象*/public void deleteUser(User user) {// 需要 user 对象有有效的 iduserRepository.delete(user);System.out.println("Deleted User: " + user);}/*** 删除所有用户 (谨慎使用!)*/public void deleteAllUsers() {userRepository.deleteAll();System.out.println("Deleted all users.");}
}

重点:

  • @Autowired 用于依赖注入 UserRepository
  • save(entity): 核心方法,既能插入新文档(如果实体没有 ID 或 ID 不存在),也能更新现有文档(如果实体有 ID 且数据库中存在)。
  • findById(id): 返回 Optional<T>,推荐使用 isPresent() 判断和 get() 获取。
  • findAll(): 返回所有文档的列表。
  • deleteById(id) / delete(entity) / deleteAll(): 执行删除操作。
  • existsById(id): 检查文档是否存在。
  • MongoRepository 提供的默认方法和自定义的方法名衍生查询,覆盖了大部分常见的简单查询场景。

8. 步骤 6: 进阶查询 - 使用 MongoTemplate

MongoRepository 提供的方法名衍生查询或 @Query 注解(此处未详细介绍,但也可用于定义 JPQL 或原生查询)无法满足复杂的查询需求时,可以使用 MongoTemplateMongoTemplate 提供了更底层、更灵活的 MongoDB 操作方式,包括复杂的查询、更新和聚合操作。

什么是 MongoTemplate?

MongoTemplate 是 Spring Data MongoDB 提供的核心类,它封装了 MongoDB Java 驱动的操作,提供了方便的 API 来执行各种数据库操作。你需要在使用它的类中注入它:

import org.springframework.data.mongodb.core.MongoTemplate;@Service
public class AdvancedUserService {@Autowiredprivate MongoTemplate mongoTemplate; // 注入 MongoTemplate// ... 方法将在这里实现 ...
}

使用 QueryCriteria

对于复杂的查询条件,我们通常使用 QueryCriteria 对象来构建。

什么是 Query?

Query 对象封装了 MongoDB 查询的所有方面,包括查询条件 (Criteria)、字段投影 (选择返回哪些字段)、排序 (Sort) 和分页 (limit, skip)。

什么是 Criteria?

Criteria 对象用于构建查询条件,类似于 SQL 中的 WHERE 子句。它提供了一系列方法 (如 is, gt, lt, regex, in, and, or 等) 来定义文档需要匹配的规则。

常用 Criteria 方法
Criteria 方法含义MongoDB 操作符SQL (MySQL) 类似
where("field").is(value)字段等于特定值$eqfield = value
where("field").ne(value)字段不等于特定值$nefield != value
where("field").lt(value)字段小于特定值$ltfield < value
where("field").lte(value)字段小于等于特定值$ltefield <= value
where("field").gt(value)字段大于特定值$gtfield > value
where("field").gte(value)字段大于等于特定值$gtefield >= value
where("field").in(list)字段值在列表/数组中$infield IN (...)
where("field").nin(list)字段值不在列表/数组中$ninfield NOT IN (...)
where("field").exists(true/false)字段存在/不存在$existsIS NOT NULL / IS NULL (概念类似)
where("field").regex(pattern)字段匹配正则表达式$regexfield REGEXP 'pattern'
where("field").regex(pattern, "i")正则表达式 (忽略大小写)$options: 'i'(取决于具体实现)
and(criteria)链式添加 AND 条件(隐式AND)AND
new Criteria().orOperator(c1, c2, ...)创建 OR 条件组合$orOR
new Criteria().andOperator(c1, c2, ...)创建 AND 条件组合$andAND
代码示例 (Query & Criteria)
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.domain.Sort; // 用于排序
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.yourproject.model.User;
import java.util.List;@Service
public class AdvancedUserService {@Autowiredprivate MongoTemplate mongoTemplate;/*** 查找年龄大于指定值,并且按姓名升序排序的用户* @param minAge 最小年龄* @return 用户列表*/public List<User> findUsersOlderThanAndSortByName(int minAge) {// 1. 创建查询条件 (Criteria)Criteria ageCriteria = Criteria.where("age").gt(minAge); // 年龄大于 minAge// 2. 创建 Query 对象,并应用 CriteriaQuery query = new Query(ageCriteria);// 3. 添加排序 (Sort)query.with(Sort.by(Sort.Direction.ASC, "user_name")); // 按 user_name 升序排序// 4. (可选) 添加分页// query.limit(10); // 限制返回最多 10 条// query.skip(20); // 跳过前 20 条 (用于分页)// 5. (可选) 添加字段投影 (只返回需要的字段)// query.fields().include("user_name", "email").exclude("_id"); // 只包含 name 和 email, 排除 _id// 6. 执行查询// find() 方法需要 Query 对象和结果映射的实体类类型List<User> users = mongoTemplate.find(query, User.class);// 如果查询的是特定集合,也可以指定集合名称: mongoTemplate.find(query, User.class, "users");System.out.println("Found users older than " + minAge + " (sorted by name): " + users);return users;}/*** 查找姓名包含 "John" (不区分大小写) 或者 邮箱以 ".com" 结尾的用户* @return 用户列表*/public List<User> findUsersByNameRegexOrEmailSuffix() {// 条件1: 姓名包含 "John" (忽略大小写)Criteria nameCriteria = Criteria.where("user_name").regex("John", "i"); // "i" 表示忽略大小写// 条件2: 邮箱以 .com 结尾Criteria emailCriteria = Criteria.where("email").regex("\\.com$", ""); // $ 表示结尾, "." 需要转义// 组合 OR 条件Criteria orCriteria = new Criteria().orOperator(nameCriteria, emailCriteria);// 创建 QueryQuery query = new Query(orCriteria);// 执行查询List<User> users = mongoTemplate.find(query, User.class);System.out.println("Found users with name regex 'John' (i) or email ending in '.com': " + users);return users;}
}

注释:

  • Criteria.where("fieldName") 开始定义一个字段的条件。
  • 可以链式调用 .is(), .gt(), .lt(), .regex() 等方法。
  • new Criteria().orOperator(criteria1, criteria2) 用于组合 OR 条件。默认情况下,链式调用或多个 Criteria 放入 QueryAND 关系。
  • Query 对象可以设置排序 (.with(Sort.by(...)))、分页 (limit(), skip()) 和字段投影 (fields().include()/exclude())。
  • mongoTemplate.find(query, EntityClass.class) 执行查询。

使用 Aggregation

MongoDB 的聚合框架 (Aggregation Framework) 是一个强大的数据处理管道,用于对集合中的文档进行多阶段处理,例如分组、计算、转换等,非常适合数据分析和报表生成。

什么是 Aggregation?

在 Spring Data MongoDB 中,Aggregation API 用于构建和执行 MongoDB 的聚合管道。管道由一系列阶段 (Stages) 组成,每个阶段对输入的文档进行处理,并将结果传递给下一个阶段。

常用聚合阶段 (Stages)
Spring Data 方法MongoDB 阶段描述SQL (MySQL) 类似
match(criteria)$match过滤文档,类似于 find 的条件WHERE / HAVING (概念上)
group(fields...)$group按指定字段分组,并进行聚合运算 (sum, avg等)GROUP BY
project(fields...)$project重塑文档结构 (选择、重命名、添加计算字段)SELECT field1, field2, calculation
sort(sort)$sort按指定字段排序ORDER BY
limit(n)$limit限制输出的文档数量LIMIT n
skip(n)$skip跳过指定数量的文档OFFSET n
unwind("field")$unwind将数组字段的每个元素拆分成独立的文档(无直接对应,类似 JOIN 或规范化)
lookup(...)$lookup执行类似 SQL 的左外连接 (Left Outer Join)LEFT JOIN
count("fieldName")$count计算输入文档的数量,并输出到指定字段SELECT COUNT(*)...
addFields(...)$addFields向文档添加新字段(无直接对应)
sortByCount("field")$sortByCount按字段值的频率分组和排序 (组合了 $group$sort)SELECT field, COUNT(*) GROUP BY field ORDER BY COUNT(*) DESC
代码示例 (Aggregation)

假设我们想按年龄分组,统计每个年龄段的用户数量,并按年龄排序。

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.aggregation.SortOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.domain.Sort;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.yourproject.model.User; // 假设有 User 类
import java.util.List;// 定义一个类来接收聚合结果 (字段名需要匹配 $project 或 $group 的输出)
class AgeGroupResult {private int age; // 对应 $group 的 _id.ageprivate long count; // 对应 $group 的 count// Getters and Setterspublic int getAge() { return age; }public void setAge(int age) { this.age = age; }public long getCount() { return count; }public void setCount(long count) { this.count = count; }@Overridepublic String toString() {return "AgeGroupResult{" + "age=" + age + ", count=" + count + '}';}
}@Service
public class AggregationService {@Autowiredprivate MongoTemplate mongoTemplate;/*** 按年龄分组统计用户数量,只统计年龄大于 18 的用户,并按年龄排序* @return 每个年龄及其对应的用户数量列表*/public List<AgeGroupResult> groupUsersByAge() {// 1. $match 阶段: 过滤年龄大于 18 的用户 (可选)MatchOperation matchStage = Aggregation.match(Criteria.where("age").gt(18));// 2. $group 阶段: 按 age 字段分组,并计算每个分组的数量 (count)//    将分组的键 (age) 放入 _id 字段中GroupOperation groupStage = Aggregation.group("age") // 按 "age" 字段分组.count().as("count"); // 计算数量,并将结果命名为 "count"// 3. $project 阶段: 重塑输出,将 _id (即 age) 映射到 age 字段,并包含 count 字段//    默认的 _id 是分组依据,我们想让它叫 "age"ProjectionOperation projectStage = Aggregation.project("count") // 选择 "count" 字段.and("_id").as("age") // 将分组产生的 "_id" (即年龄) 重命名为 "age".andExclude("_id"); // 排除掉原始的 "_id" 字段// 4. $sort 阶段: 按 age 字段升序排序SortOperation sortStage = Aggregation.sort(Sort.Direction.ASC, "age");// 5. 构建聚合管道 (按顺序添加阶段)Aggregation aggregation = Aggregation.newAggregation(matchStage,    // 先过滤groupStage,    // 再分组projectStage,  // 然后重塑输出sortStage      // 最后排序);// 6. 执行聚合查询// aggregate() 方法需要 Aggregation 对象、输入集合的名称、输出结果映射的类类型AggregationResults<AgeGroupResult> results = mongoTemplate.aggregate(aggregation,"users", // 指定要聚合的集合名称 ("users" 对应 @Document(collection = "users"))AgeGroupResult.class // 指定结果映射的类);// 7. 获取映射后的结果列表List<AgeGroupResult> mappedResults = results.getMappedResults();System.out.println("Aggregation Results (Users grouped by age > 18): " + mappedResults);return mappedResults;}
}

重点:

  • 聚合是按顺序执行的多个阶段,每个阶段的输出是下一个阶段的输入。
  • Aggregation.newAggregation(...) 用于构建整个管道。
  • match(), group(), project(), sort() 等静态方法创建对应的聚合阶段。
  • group("field") 指定分组依据的字段。.count().as("fieldName"), .sum("field").as("total"), .avg("field").as("average") 等用于在分组内进行计算。
  • project() 非常重要,用于调整输出文档的结构,使其匹配你的结果类 (AgeGroupResult)。and("_id").as("newName") 常用于重命名分组产生的 _id
  • 需要创建一个结果类(如 AgeGroupResult)来映射聚合操作的输出。字段名必须与 $project$group 阶段最后输出的字段名匹配。
  • mongoTemplate.aggregate(aggregation, inputCollectionName, OutputClass.class) 执行聚合。

9. MongoDB 操作与 SQL (MySQL) 对比

下表简要对比了 MongoDB (概念/Shell语法) 和 Spring Data MongoDB (Java API) 与 SQL (以 MySQL 为例) 的常用操作:

操作类别MongoDB (概念 / Shell 示例)Spring Data MongoDB (MongoRepository / MongoTemplate)SQL (MySQL 示例)
数据库/集合use mydatabase / db.createCollection("users")配置 spring.data.mongodb.database / @Document(collection="users") (自动创建)CREATE DATABASE mydatabase; / USE mydatabase; CREATE TABLE users (...);
插入数据db.users.insertOne({name:"A", age:30})userRepository.save(new User("A", 30))INSERT INTO users (name, age) VALUES ('A', 30);
查询所有数据db.users.find({})userRepository.findAll() / mongoTemplate.findAll(User.class)SELECT * FROM users;
条件查询db.users.find({age: {$gt: 25}})userRepository.findByAgeGreaterThan(25) / mongoTemplate.find(Query.query(Criteria.where("age").gt(25)), User.class)SELECT * FROM users WHERE age > 25;
AND 条件db.users.find({name:"A", age:30})mongoTemplate.find(Query.query(Criteria.where("name").is("A").and("age").is(30)), User.class) / userRepository.findByNameAndAge("A", 30) (衍生查询)SELECT * FROM users WHERE name = 'A' AND age = 30;
OR 条件db.users.find({$or: [{name:"A"}, {age:30}]})mongoTemplate.find(Query.query(new Criteria().orOperator(Criteria.where("name").is("A"), Criteria.where("age").is(30))), User.class)SELECT * FROM users WHERE name = 'A' OR age = 30;
更新数据db.users.updateOne({name:"A"}, {$set:{age:31}})User u = userRepository.findByName("A"); if(u!=null){ u.setAge(31); userRepository.save(u); }
(更灵活更新用 mongoTemplate.updateFirst/updateMulti)
UPDATE users SET age = 31 WHERE name = 'A';
删除数据db.users.deleteOne({name:"A"})User u = userRepository.findByName("A"); if(u!=null){ userRepository.delete(u); } / userRepository.deleteById(id)DELETE FROM users WHERE name = 'A';
排序db.users.find().sort({age: 1})userRepository.findAll(Sort.by("age")) / query.with(Sort.by(Sort.Direction.ASC, "age"))SELECT * FROM users ORDER BY age ASC;
限制数量/分页db.users.find().limit(10).skip(20)Pageable p = PageRequest.of(2, 10); userRepository.findAll(p) / query.limit(10).skip(20)SELECT * FROM users LIMIT 10 OFFSET 20;
分组统计db.users.aggregate([{$group:{_id:"$age", count:{$sum:1}}}])(见上方 Aggregation 示例)SELECT age, COUNT(*) FROM users GROUP BY age;
选择特定字段db.users.find({}, {name: 1, email: 1, _id: 0})query.fields().include("name", "email").excludeId()SELECT name, email FROM users;

关键差异:

  • Schema: MongoDB 是 Schema-less (或 Schema-flexible),集合中的文档可以有不同的结构。MySQL 是 Schema-based,表结构需要预先定义。
  • 数据模型: MongoDB 是面向文档的 (BSON/JSON 格式),支持嵌套文档和数组。MySQL 是关系型的,数据存储在行和列组成的表中。
  • 查询语言: MongoDB 使用基于 JSON 的查询语言。MySQL 使用 SQL。
  • 事务: MongoDB 从 4.0 版本开始支持多文档 ACID 事务,但使用场景和复杂性与关系型数据库有所不同。传统上关系型数据库的事务支持更成熟和广泛。
  • Join: MongoDB 通过 $lookup (聚合) 实现类似 Join 的功能,但通常鼓励通过嵌入文档引用来设计数据模型以避免复杂的 Join。MySQL 的 Join 是核心功能。

10. 重点内容总结

  1. 核心依赖: spring-boot-starter-data-mongodb 是整合的关键。
  2. 配置: 通过 application.propertiesapplication.yml 配置数据库连接,spring.data.mongodb.uri 是首选方式。
  3. 实体映射: 使用 @Document 标记类,@Id 标记主键。@Field 用于字段名映射。
  4. 基础 CRUD: 继承 MongoRepository<Entity, IdType> 接口,可以获得大量开箱即用的 CRUD 方法和强大的方法名衍生查询功能,极大简化开发。
  5. save() 方法: 同时处理插入更新操作 (Upsert)。
  6. MongoTemplate: 当需要更复杂、灵活的查询、更新或聚合操作时使用。它是执行底层 MongoDB 命令的主要入口。
  7. QueryCriteria: 使用 MongoTemplate 进行查询时,用 Criteria 构建查询条件 (类似 SQL WHERE),用 Query 封装条件、排序、分页和投影。
  8. Aggregation: 用于执行多阶段的数据处理管道(分组、计算、转换),非常适合数据分析和报表。需要定义阶段 (match, group, project, sort 等) 并按顺序组合。通常需要创建结果类来映射聚合输出。
  9. MongoDB vs SQL: 理解两者在数据模型、查询方式、事务处理和 Join 上的核心差异很重要。Spring Data MongoDB 在一定程度上抽象了这些差异,但底层概念仍然不同。

11. 结语

恭喜你!通过这篇笔记,你应该对如何在 Spring Boot 中使用 MongoDB 有了基本的了解。从简单的配置、实体映射、MongoRepository 的便捷 CRUD,到 MongoTemplate 提供的更强大查询能力 (Query, Criteria) 和数据处理能力 (Aggregation),你已经掌握了核心的使用方法。

下一步建议:

  • 动手实践:创建自己的 Spring Boot 项目,连接 MongoDB,尝试笔记中的所有示例。
  • 深入学习 QueryCriteria 的更多操作符。
  • 探索更复杂的 Aggregation 管道应用。
  • 了解 MongoDB 的索引 (@Indexed 注解) 对查询性能的重要性。
  • 研究 MongoDB 的事务 (如果你的应用场景需要)。
  • 了解 GridFS (如果需要存储大文件)。

希望这篇笔记对你的学习之旅有所帮助!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词