SpringBoot 整合 MongoDB

MySQL 适合结构化数据,Redis 适合缓存,而 MongoDB 则是介于两者之间------它是一款文档型 NoSQL 数据库 ,以类似 JSON 的 BSON 格式存储数据,结构灵活、无需预定义表结构、支持复杂查询、横向扩展方便,非常适合存储非结构化/半结构化数据


一、MongoDB 适用场景

  • • 文章、博客、评论、日志类数据(字段多变)

  • • 用户画像、行为数据、埋点上报

  • • 配置中心、动态表单、商品详情

  • • 大数据量、高写入、低事务要求的业务

  • • 需要频繁扩展字段,不想频繁改表结构


二、环境准备

  • • 安装并启动 MongoDB(本地或云服务)

  • • SpringBoot 2.x / 3.x

  • • MongoDB 客户端工具(Navicat、Mongo Compass 等)


三、引入核心依赖

go 复制代码
<!-- SpringBoot 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>

四、application.yml 配置

go 复制代码
spring:
  data:
    mongodb:
      # 无密码形式
      uri: mongodb://localhost:27017/mongo_demo

      # 有密码(账号密码+认证库)
      # uri: mongodb://root:123456@localhost:27017/mongo_demo?authSource=admin
  • mongo_demo 是数据库名,不存在会自动创建

  • • 无需手动建库建集合(collection),插入数据自动生成


五、MongoDB 常用注解

  • @Document:标记为 MongoDB 文档实体,对应集合

  • @Id:主键,默认生成 _id

  • @Field("field_name"):指定数据库字段名

  • @Transient:不存入数据库

  • @Indexed:创建索引,提升查询速度

  • @CompoundIndex:复合索引


六、实体类编写

以文章(Article)为例:

go 复制代码
package com.demo.entity;

import lombok.Data;
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.time.LocalDateTime;
import java.util.List;

@Data
@Document(collection = "article") // 指定集合名称
public class Article {

    @Id
    private String id;

    @Indexed // 为标题创建索引
    private String title;

    private String content;

    @Field("author_name")
    private String authorName;

    private Integer viewCount;

    private List<String> tags;

    private LocalDateTime createTime;

    private LocalDateTime updateTime;
}

七、两种操作方式

SpringBoot 提供两种操作 MongoDB 的方式:

    1. MongoRepository:简单 CRUD,类似 JPA
    1. MongoTemplate:灵活复杂查询、聚合、更新,生产更常用

方式一:MongoRepository 快速 CRUD

1. 编写 Repository 接口

go 复制代码
package com.demo.repository;

import com.demo.entity.Article;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ArticleRepository extends MongoRepository<Article, String> {

    // 按作者名查询
    List<Article> findByAuthorName(String authorName);

    // 按标题模糊查询
    List<Article> findByTitleLike(String title);
}

2. 基础 CRUD 示例

go 复制代码
@Service
@RequiredArgsConstructor
public class ArticleService {

    private final ArticleRepository repository;

    // 新增/修改
    public Article save(Article article) {
        article.setCreateTime(LocalDateTime.now());
        return repository.save(article);
    }

    // 根据ID查询
    public Article findById(String id) {
        return repository.findById(id).orElse(null);
    }

    // 查询所有
    public List<Article> findAll() {
        return repository.findAll();
    }

    // 删除
    public void deleteById(String id) {
        repository.deleteById(id);
    }

    // 按作者查询
    public List<Article> findByAuthor(String authorName) {
        return repository.findByAuthorName(authorName);
    }
}

方式二:MongoTemplate 复杂查询

企业开发绝大多数场景使用 MongoTemplate,灵活、强大。

1. 通用条件查询

go 复制代码
@Autowired
private MongoTemplate mongoTemplate;

// 条件构造器
Query query = new Query();

// 精确匹配
query.addCriteria(Criteria.where("authorName").is("张三"));

// 大于
query.addCriteria(Criteria.where("viewCount").gt(100));

// 模糊查询(包含)
query.addCriteria(Criteria.where("title").regex("Java"));

// 且条件
query.addCriteria(Criteria.where("authorName").is("张三").and("viewCount").gt(100));

// 或条件
query.addCriteria(new Criteria().orOperator(
        Criteria.where("authorName").is("张三"),
        Criteria.where("viewCount").gt(1000)
));

// 查询列表
List<Article> list = mongoTemplate.find(query, Article.class);

2. 分页查询

go 复制代码
// 页码从0开始
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "createTime"));
Query pageQuery = new Query().with(pageable);

List<Article> pageList = mongoTemplate.find(pageQuery, Article.class);
// 总条数
long total = mongoTemplate.count(pageQuery, Article.class);

3. 字段更新

go 复制代码
// 更新浏览量 +1
Query query = Query.query(Criteria.where("_id").is(id));
Update update = new Update().inc("viewCount", 1);
mongoTemplate.updateFirst(query, update, Article.class);

4. 批量更新

go 复制代码
mongoTemplate.updateMulti(query, update, Article.class);

5. 聚合查询(统计、分组)

go 复制代码
// 按作者分组统计文章数量
Aggregation aggregation = Aggregation.newAggregation(
        Aggregation.group("authorName").count().as("count"),
        Aggregation.sort(Sort.by(Sort.Direction.DESC, "count"))
);

AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "article", Map.class);
List<Map> mapList = results.getMappedResults();

八、MongoDB 索引

为高频查询字段加索引,性能提升巨大:

go 复制代码
// 单字段索引
@Indexed

// 唯一索引
@Indexed(unique = true)

// 复合索引
@CompoundIndex(def = "{'authorName':1, 'createTime':-1}")

创建后可在 MongoDB 中查看:

go 复制代码
db.article.getIndexes()

九、MongoDB vs MySQL 简单对比

  • • MySQL:表结构固定、事务强、适合强一致性业务

  • • MongoDB:结构灵活、无表结构约束、查询快、适合海量半结构化数据


十、注意事项

    1. 无事务默认不保证原子性,高并发需加锁或使用事务
    1. 索引不能乱建,过多索引影响写入性能
    1. 超大文档(>16MB)不适合直接存储,可存文件服务地址
    1. 模糊查询 regex 不命中索引,尽量前缀匹配
    1. 分页深度翻页性能差,建议用游标分页

十一、总结

SpringBoot 整合 MongoDB 非常简单:
引依赖 → 配连接 → 写实体 → 用 MongoTemplate / Repository

它结构灵活、开发极快,特别适合文章、评论、日志、用户行为等场景。掌握 CRUD、条件查询、分页、更新、索引,基本能覆盖 90% 的业务开发。

你在项目中用过 MongoDB 吗?一般用来存什么业务数据?有没有遇到什么坑?

欢迎在评论区留言交流,关注我,持续更新 SpringBoot 全栈实战教程。

相关推荐
sR916Mecz1 小时前
MongoDB 详解、应用场景及案例分析(AI)
数据库·mongodb
℡終嚸♂6801 小时前
Java 反序列化漏洞详解
java·开发语言
执笔画流年呀2 小时前
如何用Navicat来创建表
java·mysql
好家伙VCC2 小时前
**发散创新:基于以太坊侧链的高性能去中心化应用部署实战**在区块链生态中,*
java·python·去中心化·区块链
邂逅星河浪漫2 小时前
【JavaScript】==和===区别详解
java·javascript·==·===
kvo7f2JTy2 小时前
吃透Linux/C++系统编程:文件与I/O操作从入门到避坑
java·linux·c++
Lzh编程小栈2 小时前
数据结构与算法之队列深度解析:循环队列+C 语言硬核实现 + 面试考点全梳理
c语言·开发语言·汇编·数据结构·后端·算法·面试
_MyFavorite_2 小时前
JAVA重点基础、进阶知识及易错点总结(35)注解与反射
java·开发语言·tomcat
TON_G-T2 小时前
useEffect为什么会触发死循环
java·服务器·前端