【SpringBoot从初学者到专家的成长20】SpringBoot集成MongoDB:非关系型数据库的探索
在现代开发中,数据库是我们应用程序的重要组成部分。随着应用需求的多样化,传统的关系型数据库(如MySQL、PostgreSQL)逐渐暴露出一些扩展性和灵活性方面的瓶颈。而非关系型数据库(NoSQL)由于其高性能、低延迟和高可扩展性,越来越受到开发者的青睐。
1. SpringBoot概述
SpringBoot 是一个开源的 Java 框架,在现在国内的JAVA开发圈中基本已经处于霸主地位。熟练使用SPRINGBOOT可以大大简化了Spring应用的开发过程。Spring Boot 提供了很多提高效率的功能,录入约定大于配置的理念,并自动配置了大部分常用功能,使得开发者不必写大量配置代码,能够专注于业务逻辑。
- 自动配置:Spring Boot提供了强大的自动配置功能,能够自动配置常见的开发框架和中间件。
- 内嵌式Web服务器:Spring Boot 默认集成了Tomcat、Jetty等Web服务器,可以无需外部服务器进行开发和部署。
- 生产就绪:提供了很多生产环境需要的功能,如健康检查、监控等。
2. 非关系型数据库(NoSQL)
非关系型数据库(NoSQL)是与传统的关系型数据库(RDBMS)不同的一类数据库,它们与关系型数据库最大的区别在于不使用传统的表格结构来存储数据,而是通过更灵活的数据模型来进行数据存储。与关系型数据库的结构化查询语言(SQL)不同,NoSQL数据库通常具有以下特点:
- 灵活的数据模型:可以存储结构化、半结构化和非结构化的数据。
- 高可扩展性:支持分布式架构,易于横向扩展。
- 高性能:针对特定场景进行了优化,能处理大量的数据。
常见的NoSQL数据库包括:MongoDB、Cassandra、Redis、Couchbase、Elasticsearch等:
- MongoDB 适合大多数Web应用和实时分析,特别是需要灵活数据模型和高可扩展性的场景。
- Cassandra 适用于高吞吐量的分布式系统,如日志处理和实时数据流。
- Redis 主要用于缓存和短期数据存储,适合快速访问的应用。
- CouchDB 适合分布式、文档型存储的应用,尤其是面向Web和RESTful API的开发。
- HBase 主要用于大规模数据存储和分析,尤其是与Hadoop集成的应用场景。
- Neo4j 是最佳的图数据库解决方案,适用于处理复杂关系和网络数据的场景。
- Elasticsearch 强于搜索和分析大规模文本数据,适合实时搜索引擎和日志分析。
- DynamoDB 适合AWS生态系统中的高可用、低延迟、可扩展应用。
- Accumulo 则是针对需要强安全性和细粒度访问控制的大数据分析应用。
以下是目前主要的非关系型数据库及其优缺点和适用场景的表格:
| 数据库类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| MongoDB | - 数据存储灵活(文档存储,支持JSON格式) - 高性能,支持高并发读写 - 支持横向扩展,易于分片 - 良好的查询能力,支持聚合查询和索引 | - 不支持ACID事务(除非启用分布式事务) - 对复杂的关系型数据处理较弱 - 存储空间较大,尤其是存储大量小文档时 | - 社交网络、内容管理系统(CMS)、实时分析、日志处理、大数据分析 |
| Cassandra | - 高可扩展性和高可用性 - 良好的写入性能,适合写密集型场景 - 支持分布式架构,自动分片 | - 查询不如传统的关系型数据库灵活 - 不支持复杂的JOIN查询 - 事务支持较弱 | - 大规模实时数据处理、分布式日志分析、推荐系统、实时监控 |
| Redis | - 高速的内存数据存储,读写性能极高 - 支持丰富的数据结构,如字符串、列表、集合、哈希表等 - 支持持久化存储(RDB、AOF) | - 数据存储基于内存,成本较高 - 适合短期存储,不适合大规模持久化存储 - 数据持久化可能对性能产生影响 | - 缓存系统、会话管理、消息队列、实时计数、排行榜 |
| CouchDB | - 使用MapReduce进行查询,支持高效的全文检索 - 易于扩展,支持分布式架构 - 数据为JSON格式,支持RESTful API | - 查询性能不如传统关系型数据库 - 适合高写负载,读负载较弱 - 不支持复杂的SQL查询 | - 分布式Web应用、IoT数据存储、日志处理、应用程序数据存储 |
| HBase | - 强大的横向扩展能力,支持大规模数据存储 - 适合实时读写和批处理的应用场景 - 基于Hadoop生态系统,支持MapReduce分析 | - 不适合复杂的查询操作(例如JOIN操作) - 数据模型复杂,学习曲线较陡峭 - 不支持传统的事务操作 | - 大数据存储和分析、时间序列数据、推荐引擎 |
| Neo4j | - 高效的图形数据库,适合复杂的关系型查询 - 专门用于存储和查询图形数据 - 支持ACID事务,保障数据一致性 | - 不适合大规模的结构化数据存储 - 扩展性和性能相对较弱 - 查询性能对于大规模数据可能较低 | - 社交网络分析、推荐系统、路径分析、网络安全 |
| Elasticsearch | - 强大的全文搜索和分析能力 - 高性能,支持海量数据检索 - 实时搜索,支持快速数据更新 | - 数据持久化不如传统数据库 - 存储空间需求较高 - 配置和管理复杂,尤其是在集群模式下 | - 实时搜索引擎、日志分析、大数据分析、全文检索 |
| DynamoDB | - 完全托管的NoSQL数据库,免维护 - 高可用性和自动扩展 - 支持自动分区,适合大规模应用 | - 数据一致性相对较弱(CAP定理中的可用性优先) - 查询和写入操作的限制较多 | - 高并发的Web应用、物联网(IoT)、移动应用后台 |
| Apache Accumulo | - 基于HBase,增强了安全性和细粒度的访问控制 - 支持分布式查询和高可扩展性 - 易于与Hadoop集成 | - 配置和管理较复杂 - 性能不如HBase的某些应用场景 - 存储和计算资源消耗较大 | - 数据仓库、大数据分析、需要细粒度访问控制的应用 |
3. MongoDB概述
MongoDB 是一种流行的非关系型数据库,基于文档存储模型,使用 BSON(类似于 JSON)格式存储数据。它具有以下特点:
- 文档存储:数据以文档形式存储,每个文档是一个自描述的JSON对象。
- 高性能:对大量数据的读取和写入操作进行了优化。
- 横向扩展:支持分片和副本集,可以轻松扩展到多个服务器。
- 灵活的查询:支持丰富的查询功能,包括聚合操作、索引、地理位置查询等。
MongoDB的特点使得它在处理文档方面有独特的优势,因此现在很多公司和团队都在使用MongoDB来替换数据库中的Blob和clob字段,毕竟在数据库中存储大字段会带来很多额外的性能开销。
4. MongoDB主要API
在MongoDB中,主要通过以下几个核心API进行数据的操作:
- MongoClient:MongoDB的客户端类,用于连接数据库。
- MongoDatabase:代表一个数据库。
- MongoCollection:代表一个集合,相当于关系型数据库中的表。
- MongoCursor:用于遍历查询结果集。
- DBObject:MongoDB中的对象,常用于数据的插入、查询等操作。
常用的MongoDB操作包括:
find(): 查询数据insert(): 插入数据update(): 更新数据remove(): 删除数据aggregate(): 聚合查询
MongoDB系统系统框架如如下(仅供参考):

5. Spring Boot 中 MongoDB的 Maven配置
要在Spring Boot项目中集成MongoDB,首先需要在pom.xml中添加MongoDB相关的依赖。Spring Boot 提供了spring-boot-starter-data-mongodb来简化集成过程。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
6. Spring Boot 中 MongoDB的 Gradle配置
对于Gradle用户,可以在build.gradle文件中添加如下依赖:
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
7. Spring Boot 集成 MongoDB 的配置
在application.properties中配置MongoDB连接信息:
spring.data.mongodb.uri=mongodb://username:password@localhost:27017/databaseName
# 或者使用单独配置
# spring.data.mongodb.host=localhost
# spring.data.mongodb.port=27017
# spring.data.mongodb.database=databaseName
# spring.data.mongodb.username=username
# spring.data.mongodb.password=password
# spring.data.mongodb.authentication-database=admin
# spring.data.mongodb.authentication-mechanism=SCRAM-SHA-1
# spring.data.mongodb.ssl=false
# spring.data.mongodb.replica-set=replicaSetName
# spring.data.mongodb.connections-per-host=100
# spring.data.mongodb.max-wait-time=12000
# spring.data.mongodb.socket-timeout=2000
# spring.data.mongodb.min-connections=10
# spring.data.mongodb.max-connections=100
# spring.data.mongodb.max-connection-idle-time=600000
# spring.data.mongodb.server-selection-timeout=3000
# spring.data.mongodb.heartbeat-frequency=10000
# spring.data.mongodb.retry-writes=true
# spring.data.mongodb.read-preference=primary
# spring.data.mongodb.read-concern=majority
# spring.data.mongodb.write-concern=majority
或者在application.yml中配置:
spring:data:mongodb:uri: mongodb://username:password@localhost:27017/databaseName# 或者使用单独配置# host: localhost# port: 27017# database: databaseName# username: username# password: password# authentication-database: admin# authentication-mechanism: SCRAM-SHA-1# ssl: false# replica-set: replicaSetName# connections-per-host: 100# max-wait-time: 12000# socket-timeout: 2000# min-connections: 10# max-connections: 100# max-connection-idle-time: 600000# server-selection-timeout: 3000# heartbeat-frequency: 10000# retry-writes: true# read-preference: primary# read-concern: majority# write-concern: majority
各个配置项的说明和性能影响见表格:
| 配置项 | 解释说明 | 性能影响 |
|---|---|---|
spring.data.mongodb.uri | MongoDB连接字符串,包含用户名、密码、主机、端口和数据库名称。 | 无 |
spring.data.mongodb.host | MongoDB服务器主机地址,默认为localhost。 | 无 |
spring.data.mongodb.port | MongoDB服务器端口,默认为27017。 | 五。 |
spring.data.mongodb.database | 要连接的MongoDB数据库名称。 | 无。 |
spring.data.mongodb.username | 连接MongoDB时使用的用户名。 | 无。 |
spring.data.mongodb.password | 连接MongoDB时使用的密码。 | 无 |
spring.data.mongodb.authentication-database | 用于身份验证的数据库,通常是admin。 | 轻微 |
spring.data.mongodb.authentication-mechanism | MongoDB认证机制,通常为SCRAM-SHA-1或SCRAM-SHA-256。 | 使用更复杂的认证机制(如SCRAM-SHA-256)会增加认证时的计算开销,可能稍微影响连接速度。 |
spring.data.mongodb.ssl | 是否启用SSL/TLS加密连接,默认false。 | 启用SSL会增加加密/解密的开销,可能导致连接延迟和数据传输速度下降,尤其是在高负载下。 |
spring.data.mongodb.replica-set | MongoDB副本集的名称,用于高可用性配置。 | 可能会增加延迟。 |
spring.data.mongodb.connections-per-host | 每个主机的最大连接数。 | 适当并发数可提高系统并发性能。 |
spring.data.mongodb.max-wait-time | 在连接池中没有可用连接时,等待的最大时间(毫秒)。 | 较长的等待时间可以避免请求被立即拒绝,但如果配置过长,可能导致客户端等待响应的时间增加,影响性能。 |
spring.data.mongodb.socket-timeout | 等待MongoDB响应时的最大超时时间(毫秒)。 | 过短的超时可能导致频繁的连接断开。 |
spring.data.mongodb.min-connections | 连接池中最小连接数。 | 减少连接建立的延迟,但是需要关注内存占用 |
spring.data.mongodb.max-connections | 连接池中最大连接数。 | 根据运行时的性能情况调整,避免过大的连接数耗尽系统内存。 |
spring.data.mongodb.max-connection-idle-time | 连接池中连接的最大空闲时间(毫秒)。 | 根据系统运行时的性能情况调整。 |
spring.data.mongodb.server-selection-timeout | 选择服务器时的超时时间(毫秒)。 | 轻微,过长的等待时间影响连接效率。 |
spring.data.mongodb.heartbeat-frequency | 副本集心跳频率(毫秒)。 | 轻微。当网络延迟高时可能导致系统性能急剧下降 |
spring.data.mongodb.retry-writes | 是否启用写操作重试。 | 轻微,可能增加磁盘IO |
spring.data.mongodb.read-preference | 读取偏好设置,定义从哪个节点读取数据,如primary、secondary等。 | 无性能影响,但是可能导致数据一致性问题 |
spring.data.mongodb.read-concern | 读取一致性级别,通常为majority。 | `无,有的网络文章说可能导致读延迟,但是我在实际测试中的数据不支持这个结论。 |
spring.data.mongodb.write-concern | 写入一致性级别,通常为majority。 | `增加写延迟,可能影响数据库TPS。 |
8. Spring Boot中访问MongoDB的实例
下面是一个Spring Boot项目中如何通过MongoDB进行数据操作的简单实例。
- 创建实体类:
package com.example.demo.model;import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;@Document(collection = "users")
public class User {@Idprivate String id;private String name;private int age;// Getters and Setters
}
- 创建Repository接口:
package com.example.demo.repository;import com.example.demo.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;public interface UserRepository extends MongoRepository<User, String> {// 自定义查询方法User findByName(String name);
}
- 创建Service类:
package com.example.demo.service;import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public List<User> getAllUsers() {return userRepository.findAll();}public User getUserByName(String name) {return userRepository.findByName(name);}public User saveUser(User user) {return userRepository.save(user);}public void deleteUser(String id) {userRepository.deleteById(id);}
}
- 创建Controller类:
package com.example.demo.controller;import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMappingpublic List<User> getAllUsers() {return userService.getAllUsers();}@GetMapping("/{name}")public User getUserByName(@PathVariable String name) {return userService.getUserByName(name);}@PostMappingpublic User createUser(@RequestBody User user) {return userService.saveUser(user);}@DeleteMapping("/{id}")public void deleteUser(@PathVariable String id) {userService.deleteUser(id);}
}
9. 总结
通过Spring Boot与MongoDB的集成,我们能够更轻松地在现代Web应用中使用非关系型数据库。Spring Boot为我们提供了简洁的配置和强大的自动化支持,使得MongoDB的操作更加方便。非关系型数据库特别适合需要高性能和高可扩展性的应用场景,MongoDB作为其中的佼佼者,为开发者提供了丰富的功能和易于使用的API。
