Spring Boot 集成 MongoDB:从入门到生产实践
itomcoil 2025-09-04 07:58 5 浏览
1、MongoDB 简介
MongoDB 是一个开源的、面向文档的 NoSQL 数据库,旨在提供高性能、高可用性和易扩展性。它与传统的关系型数据库(如 MySQL)有着根本性的区别。
- 面向文档(Document-Oriented):数据以 BSON(Binary JSON)文档的形式存储,结构类似于 JSON 对象。一个文档相当于关系型数据库中的一行,但一个文档中可以存储非常复杂的、嵌套的数据结构。
- 模式自由(Schema-less):集合(Collection,类似于表)中的文档不需要具有相同的字段集。这提供了极大的灵活性,允许你在不中断应用程序的情况下动态调整数据结构。
- 高性能:通过嵌入式数据模型、索引、复制和分片等特性,MongoDB 可以提供极高的读写吞吐量。
- 高可用性:通过副本集(Replica Set) 提供自动故障转移。副本集是一组维护相同数据集的 MongoDB 服务器,确保了数据的冗余和服务的连续性。
- 易扩展性:通过分片(Sharding) 实现水平扩展。分片将数据分布到一个集群中的多台机器上,以应对海量数据和高并发场景。
核心概念对比:
MongoDB 被设计用来满足现代应用程序的需求,特别是那些需要处理大量非结构化或半结构化数据的应用场景,比如内容管理系统、实时分析、移动应用后端等。由于其灵活性和性能优势,MongoDB 成为许多开发者和企业的首选数据库解决方案之一。
2、MongoDB 安装
这里以在本地开发环境(如 macOS 、Linux 和 Windows)安装为例。
2.1. macOS (使用 Homebrew)
# 1. 更新 Homebrew
brew update
# 2. 安装 MongoDB Community Edition
brew tap mongodb/brew
brew install mongodb-community
# 3. 启动 MongoDB 服务
brew services start mongodb-community
# 4. (可选) 连接验证
mongosh
2.2. Windows
- 访问 MongoDB Community Server 下载页面:https://www.mongodb.com/try/download/community
- 选择版本,下载 .msi 安装包。
- 运行安装程序,建议选择 "Complete" 完整安装。
- 安装完成后,MongoDB 通常会被安装到 D:\Program Files\MongoDB。
- 创建数据存储目录:D:\data\MongoDB。
- 通过命令行启动 MongoDB 服务:
# 切换到 MongoDB 的 bin 目录
cd D:\Program Files\MongoDB\Server\{version}\bin
# 启动 mongod 进程
mongod.exe
- 保持该窗口运行,另开一个命令行窗口,运行 mongosh.exe 来连接数据库。
2.3. Linux安装
下载MongoDB Community Server
下载地址:
https://www.mongodb.com/try/download/community
解压后启动MongoDB Server:
#创建dbpath和logpath
mkdir -p /mongodb/data /mongodb/log
#进入mongodb目录,启动mongodb服务
bin/mongod --port=27017 --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log
2.4. Docker (跨平台推荐)
对于开发和测试,Docker 是最简单、干净的方式。
# 拉取最新镜像
docker pull mongo
# 运行容器
docker run -d --name my-mongo -p 27017:27017 mongo:latest
# 进入容器内的 shell 进行操作
docker exec -it my-mongo mongosh
3、MongoDB 基本命令使用
通过 mongosh 连接数据库后,可以执行以下基本命令。
// 查看所有数据库
show dbs
// 切换/创建数据库 (如果数据库不存在,插入第一条数据时会自动创建)
use testdb
// 查看当前数据库中的集合
show collections
// 插入文档(insertOne/insertMany)
db.users.insertOne({name: "Alice", age: 25, email: "alice@example.com", hobbies: ["reading", "hiking"]})
db.users.insertMany([{name: "Bob", age: 30}, {name: "Charlie", age: 35}])
// 查询文档(find)
db.users.find() // 查询所有
db.users.findOne({name: "Alice"}) // 查询一个
db.users.find({age: {$gt: 25}}) // 查询年龄大于25的
// 更新文档(updateOne/updateMany)
db.users.updateOne({name: "Alice"}, {$set: {age: 26}}) // 设置字段
db.users.updateMany({age: {$lt: 30}}, {$inc: {age: 1}}) // 自增
// 删除文档(deleteOne/deleteMany)
db.users.deleteOne({name: "Charlie"})
db.users.deleteMany({age: {$gt: 40}})
// 创建索引
db.users.createIndex({email: 1}) // 1为升序,-1为降序
db.users.createIndex({name: 1, age: -1}) // 复合索引
4、SpringBoot集成MongoDB
4.1、环境准备
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
完整依赖如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</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-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
4.2、配置
application.properties
# MongoDB
spring.data.mongodb.host = 127.0.0.1
spring.data.mongodb.port = 27017
spring.data.mongodb.database = test
spring.data.mongodb.auto-index-creation = true
# 或者直接使用uri方式
#spring.data.mongodb.uri=mongodb://user:password@127.0.0.1:27017/test?authSource=admin&maxPoolSize=100&minPoolSize=10&maxIdleTimeMS=60000&waitQueueTimeoutMS=120000&connectTimeoutMS=10000&socketTimeoutMS=30000
# 打印mongoDB日志
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
logging.level.org.mongodb.driver.connection=DEBUG
连接配置可参考文档 https://www.mongodb.com/zh-cn/docs/manual/reference/connection-string/
4.3、文档操作
1、新增实体
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(collection = "person") // 指定集合名称
public class Person {
@Id // 映射文档中的_id
private Long id;
private String name;
private Integer age;
}
2、添加集合文档
集合操作时注入MongoTemplate
@SpringBootTest(classes = MongoApplication.class)
@RunWith(SpringRunner.class)
public class InsertTests {
@Resource
private MongoTemplate mongoTemplate;
@Test
public void testInsert() {
Person person = Person.builder().id(2L).name("river").age(18).build();
mongoTemplate.insert(person);
// 如果有就修改, 没有就插入
mongoTemplate.save(Person.builder().id(2L).name("zhangsan").age(28).build());
// 批量写入
List<Person> persons = new ArrayList<>();
for (int i = 100; i <= 150; i++) {
person = Person.builder().id(Long.valueOf(i)).name("lisi" + i).age(i).build();
persons.add(person);
}
mongoTemplate.insertAll(persons);
}
}
插入数据时: insert插入的_id 不能有重复,否则会报 DuplicateKeyException 提示主键重复; save对已存在的数据进行更新;
批处理操作时: insertAll可以一次性插入所有数据,效率较高;save需遍历所有数据,一次插入或更新,效率较低。
3、查询集合文档
@Slf4j
@SpringBootTest(classes = MongoApplication.class)
@RunWith(SpringRunner.class)
public class QueryTests {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void find() {
// 查询集合中的全部文档数据
List<Person> personList = mongoTemplate.findAll(Person.class);
log.info("查询结果:{}", personList);
// 查询集合中指定的ID文档数据
Person byId = mongoTemplate.findById(1L, Person.class);
log.info("查询结果:{}", byId.toString());
// 根据条件查询符合条件的文档数据并返回第一条数据
Query query = new Query(Criteria.where("name").is("river"));
Person result = mongoTemplate.findOne(query, Person.class);
log.info("查询结果:{}", result);
// 根据条件查询所有符合条件的文档
query = new Query(Criteria.where("age").gt(18));
List<Person> list = mongoTemplate.find(query, Person.class);
log.info("查询结果:{}", list);
// 创建查询对象,然后将条件对象添加到其中
Criteria criteria = Criteria.where("age").gt(18).lte(30);
query = new Query(criteria);
list = mongoTemplate.find(query, Person.class);
log.info("查询结果:{}", list);
Criteria name = Criteria.where("name").is("zhangsan");
Criteria age = Criteria.where("age").is(18);
// 创建条件对象,将上面条件进行 AND 关联
criteria = new Criteria().andOperator(name, age);
query = new Query(criteria);
list = mongoTemplate.find(query, Person.class);
log.info("查询结果:{}", list);
// 从第5行开始,查询3条数据返回
query = new Query(Criteria.where("age").is("20"))
.with(Sort.by("id"))
.limit(3).skip(5);
list = mongoTemplate.find(query, Person.class);
log.info("查询结果:{}", list);
}
}
Criteria是标准查询的接口,可以引用静态的Criteria.where的把多个条件组合在一起,就可以轻松地将多个方法查询连接起来,方便我们操作查询语句。
4、更新集合文档
@Slf4j
@SpringBootTest(classes = MongoApplication.class)
@RunWith(SpringRunner.class)
public class UpdateTests {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void update() {
Person person = mongoTemplate.findById(1L, Person.class);
person.setName("wangwu");
mongoTemplate.save(person);
Query query = new Query(Criteria.where("id").is(1L));
// 修改内容
Update update = new Update().set("name", "lisi");
UpdateResult updateResult = mongoTemplate.updateMulti(query, update, Person.class);
// // 只更新满足条件的第一条记录
// UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Person.class);
// 没有符合条件的记录则插入数据
// // update.setOnInsert("id",11); // 指定_id
// updateResult = mongoTemplate.upsert(query, update, Person.class);
// 返回修改的记录数
log.info("updateResult: {}", updateResult.getModifiedCount());
}
}
如果更新后的结果和更新前的结果是相同,返回0。
updateFirst() 只更新满足条件的第一条记录
updateMulti() 更新所有满足条件的记录
upsert() 没有符合条件的记录则插入数据
5、删除集合文档
@Slf4j
@SpringBootTest(classes = MongoApplication.class)
@RunWith(SpringRunner.class)
public class DeleteTests {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void delete() {
// 删除id为1的记录
Query query = new Query(Criteria.where("id").is(1L));
DeleteResult remove = mongoTemplate.remove(query, Person.class);
log.info("删除的条数为:{}", remove.getDeletedCount());
// 删除符合条件的单个文档并返回删除的文档
query = new Query(Criteria.where("id").is(2L));
Person per = mongoTemplate.findAndRemove(query, Person.class);
log.info("删除的文档: {}", per);
}
}
4.4、去掉_class属性
使用MongoTemplate写入文档时,会自动将_class属性添加到文档中,一般不需要使用_class属性,可以配置去掉_class属性。
@Configuration
public class MongoConfig {
@Bean("mongoTemplate")
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext mongoMappingContext) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
// 去掉_class字段
mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return new MongoTemplate(mongoDbFactory, mappingMongoConverter);
}
}
4.5、忽略字段
忽略字段,即不将字段写入到数据库中,可以通过注解@Transient实现。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(collection = "person") // 指定集合名称
public class Person {
@Id // 映射文档中的_id
private Long id;
private String name;
@Transient
private Integer age;
}
5、使用时注意事项
- 正确使用索引:分析查询模式,为经常查询的字段、排序字段创建索引。避免全集合扫描。但索引不是越多越好,它会占用空间并降低写操作性能。
- 设计文档结构:嵌入式(Embed) vs 引用式(Reference):对于一对一且不频繁变化的关系,使用嵌入式(将子文档直接放在主文档中)。对于一对多或多对多且频繁查询独立的关系,使用引用式(存储另一个文档的 _id)。
- 避免大文档:MongoDB 单个文档大小限制为 16MB。避免无限制地增长数组。
- 使用 Repository 抽象层:充分利用 Spring Data 的派生查询和 @Query 注解,减少手写模板代码。
- 连接池配置:生产环境中,务必在 application.properties 中配置连接池参数,以避免资源耗尽。
- 使用 MongoTemplate 进行复杂操作:对于复杂的聚合查询、更新操作,可以直接注入 MongoTemplate,它提供了更细粒度的控制。
- 绝不使用单节点:生产环境必须部署副本集(Replica Set)。这提供了数据冗余、高可用和自动故障转移能力。
- 启用认证和授权:为 MongoDB 实例设置用户名和密码,并遵循最小权限原则,为应用创建专属用户,只授予其必要的数据库操作权限。
- 备份与恢复:制定并定期测试备份策略。可以使用 mongodump/mongorestore 或文件系统快照等工具。
- 监控与告警:监控数据库的关键指标,如内存使用率、CPU 使用率、操作计数器、复制延迟等。
6、总结
Spring Boot 与 MongoDB 的集成极大地简化了 Java 开发者使用 NoSQL 数据库的流程。通过 Spring Data MongoDB,我们可以用面向对象的方式高效地操作 MongoDB,几乎不需要编写底层的数据库代码,然而,将 MongoDB 用于生产环境务必做好副本集、安全、备份和监控,才能构建出稳定、可靠的应用系统。对于大多数 Web 应用,尤其是需要处理多样化数据、高吞吐读写的场景,Spring Boot + MongoDB 是一个不错的技术组合。
相关推荐
- NAS下搭建FastGpt,一个基于 LLM 大语言模型的知识库问答系统
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:熊猫不是猫QAQ前言FastGPT是一个基于LLM大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过Flow可...
- MongoDB入门实操《二》_mongodb从入门到商业实战
-
常规命令使用首先我们来了解几个概念,虽然MongoDB入门实操《上篇》这篇文章已经提到过,这里再次加深印象:集合:Mongo中的集合就是mysql的表的表现形式文档:文档的数据结构和JSON基本...
- Go语言零到一:数据库交互_go语言数据库连接池
-
引言Go语言的database/sql包为开发者提供了一个抽象层,使得与MySQL数据库的交互变得更加容易。1.安装MySQL驱动为了能够与MySQL数据库通信,我们需要安装go...
- Java中使用MongoDB数据库_java操作mongo
-
一、Java实现对MongDB的操作1、前提条件除了通过启动mongo进程进如Shell环境访问数据库外,MongoDB还提供了其他基于编程语言的访问数据库方法。MongoDB官方提...
- Spring Boot 集成 MongoDB:从入门到生产实践
-
1、MongoDB简介MongoDB是一个开源的、面向文档的NoSQL数据库,旨在提供高性能、高可用性和易扩展性。它与传统的关系型数据库(如MySQL)有着根本性的区别。面向文档(Docum...
- 发现一个不错的库推荐给大家:DuckDB + Python + Pandas 量化研究利器
-
大家好,我是花姐。最近折腾数据处理的时候,发现了一个宝藏库——DuckDB,配合Python和Pandas简直不要太香!今天我就聊聊它到底有多好用,特别适合我们搞量化研究的同学。1.Duck...
- SpringBoot 自研「轻量级 API 防火墙」:单机内嵌,支持在线配置
-
1.背景与痛点在做后端开发时,我们常常会遇到这样的困境:接口被恶意刷流量:比如某个查询接口被短时间大量调用,数据库连接数打满,最终拖垮整个服务。缺少细粒度防护能力:很多系统只有粗糙的全局限流,但某些...
- 福建新画卷,把福建成绩“画”给你看
-
·x-_p-_o-[U2FsdGVkX1/DHR1fwp5qMkbHvRjusk9BgvDHM/8zbH+7Z+bZnW0jD3Vk67FnKGbJHp2L4vKFqg7ryQ7Zadr0+p+82E...
- [续]江西话汉语赣方言之叠词_江西话什么意思
-
一、赣语耒阳话每次去湖南耒阳,老俵听到我是江西人,都分外亲切:“我们祖上是从江西迁过来的!”在得知明朝初年湖广因战乱赤地千里,耒阳人祖上大都从江西永新迁来后,我就特别留意耒阳方言:耒阳话不仅保留了老...
- SpringBoot 在线依赖包漏洞扫描仪,一键发现潜在安全漏洞
-
在日常项目开发中,依赖第三方库几乎是不可避免的。从spring-boot-starter到MyBatis、Log4j,再到各种工具类库,几乎每个应用都需要几十甚至上百个依赖。然而,这些依赖并非完...
- 一文学会Python的变量命名规则!_简述python变量命名规则
-
目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...
- Python中8种Functools使用方法_python functools.partial
-
在本文中,我们来看看functools标准库模块以及您可以用它做的6件很酷的事情1.缓存可以使用@cache装饰器(以前称为@lru_cache)作为“简单的轻量级无界函数缓存”。典型的例子是...
- 每天5分钟,python 速成(59)_python速成视频教程
-
首先明确学习目标,今天的目标是python中模块学习模块模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块importrandomimportmath#数学相...
- 珍藏版-11款爱心的免费公布的数学方程式和可视化-python版
-
一,图:1直角坐标系(9款):2追加一款:直角坐标系:3极坐标系(1款):二,爱心的数学方程式:1直角坐标系:1.1方程式1:Love-1进行转换:python代码中需要进行修改为:x=...
- 12种不同方法教你用Python性能优化!(建议收藏)
-
前言:今天为大家带来的内容是12种不同方法教你用Python性能优化!希望通过本文的内容能够帮助到各位!(代码块是用图片的方式呈现出来)1.减少冗余数据如用上三角或下三角的方式去保存一个大的对称矩阵。...
- 一周热门
- 最近发表
-
- NAS下搭建FastGpt,一个基于 LLM 大语言模型的知识库问答系统
- MongoDB入门实操《二》_mongodb从入门到商业实战
- Go语言零到一:数据库交互_go语言数据库连接池
- Java中使用MongoDB数据库_java操作mongo
- Spring Boot 集成 MongoDB:从入门到生产实践
- 发现一个不错的库推荐给大家:DuckDB + Python + Pandas 量化研究利器
- SpringBoot 自研「轻量级 API 防火墙」:单机内嵌,支持在线配置
- 福建新画卷,把福建成绩“画”给你看
- [续]江西话汉语赣方言之叠词_江西话什么意思
- SpringBoot 在线依赖包漏洞扫描仪,一键发现潜在安全漏洞
- 标签列表
-
- ps图案在哪里 (33)
- super().__init__ (33)
- python 获取日期 (34)
- 0xa (36)
- super().__init__()详解 (33)
- python安装包在哪里找 (33)
- linux查看python版本信息 (35)
- python怎么改成中文 (35)
- php文件怎么在浏览器运行 (33)
- eval在python中的意思 (33)
- python安装opencv库 (35)
- python div (34)
- sticky css (33)
- python中random.randint()函数 (34)
- python去掉字符串中的指定字符 (33)
- python入门经典100题 (34)
- anaconda安装路径 (34)
- yield和return的区别 (33)
- 1到10的阶乘之和是多少 (35)
- python安装sklearn库 (33)
- dom和bom区别 (33)
- js 替换指定位置的字符 (33)
- python判断元素是否存在 (33)
- sorted key (33)
- shutil.copy() (33)