深入解析:Java-155 MongoDB Spring Boot 连接实战 | Template vs Repository(含索引与常见坑)

TL;DR

场景:Spring Boot 连接 MongoDB,Template/Repository 两种姿势。
结论:5 分钟跑通;含 MRE、索引与常见坑。
产出:application.yaml、实体/Repo/模板示例、集成测试样例。

Spring Boot 连接 MongoDB 实战 | Template vs Repository

快速启动MongoDB开发环境

如果你还没有MongoDB的开发环境,可以使用Docker在本地快速部署一个独立运行的MongoDB实例。这种方式特别适合开发测试场景,能够免除复杂的安装配置过程。

使用Docker Compose启动MongoDB

我们推荐使用Docker Compose来管理容器化部署,下面是一个完整的compose.yaml配置文件:

# compose.yaml
version: '3.8'  # 指定Compose文件格式版本
services:
mongo:
image: mongo:7  # 使用官方MongoDB 7.0版本的镜像
container_name: mongodb-container  # 为容器指定名称
ports:
- "37017:27017"  # 将容器内部的27017端口映射到主机的37017端口
environment:
- MONGO_INITDB_ROOT_USERNAME=admin  # 设置管理员用户名
- MONGO_INITDB_ROOT_PASSWORD=admin123  # 设置管理员密码
volumes:
- mongo_data:/data/db  # 持久化数据存储
volumes:
mongo_data:  # 声明数据卷,确保数据持久化

启动步骤

  1. 将上述内容保存为compose.yaml文件
  2. 打开终端,导航到文件所在目录
  3. 执行命令:docker-compose up -d

启动命令与连接:

docker compose up -d
export MONGODB_URI='mongodb://admin:admin123@localhost:37017/wzk_test?authSource=admin'

连接说明

启动成功后,你可以通过以下方式连接MongoDB:

  • 连接字符串:mongodb://admin:admin123@localhost:37017
  • 使用MongoDB Compass等GUI工具连接
  • 通过命令行工具:mongo --port 37017 -u admin -p admin123 --authenticationDatabase admin

此配置提供了一个安全的基础环境,包含了:

  • 最新的MongoDB 7.0版本
  • 预设的管理员账户
  • 数据持久化存储
  • 端口映射避免与本地可能已安装的MongoDB冲突

Spring Boot 访问

Template方式

Maven

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

对应的内容如下所示:
mongodb maven

修改配置

spring:
data:
mongodb:
uri: mongodb://admin:admin123@localhost:37017/wzk_test?authSource=admin

在生产环境中,可以使用环境变量的方式:

spring:
data:
mongodb:
uri: ${MONGODB_URI:mongodb://admin:admin123@localhost:37017/wzk_test?authSource=admin}

DAO

@Autowired
private MongoTemplate mongoTemplate;

编写代码

// 使用了 Lombok
@Component
@RequiredArgsConstructor
public class WzkDao {
private final MongoTemplate mongo;
public List<WzkDocument> findAdults() {
  Query q = new Query(Criteria.where("age").gte(18));
  return mongo.find(q, WzkDocument.class);
  }
  }

Repository方式

编写实体

在实体类上

@Document("集合名")

比如我们写一个类:

package icu.wzk.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
// 可以使用 Lombok
@Document("wzk_document")
public class WzkDocument {
@Id
private String id;
@Indexed // 如 name 需要频繁查询,建议建索引;唯一可用 unique = true
private String name;
private Integer age;
// getter/setter/构造略
}

对应的截图如下所示:
mongodb java document

继承类

package icu.wzk.dao;
import icu.wzk.model.WzkDocument;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface WzkDocumentRepo extends MongoRepository<WzkDocument, String> {
  WzkDocument findByName(String name);
  }

java mongodb interface

我们可以通过如下的方式使用,这里就不过多进行介绍了:

package icu.wzk;
import icu.wzk.dao.WzkDocumentRepo;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@RequiredArgsConstructor
public class WzkStartApp {
public static void main(String[] args) {
SpringApplication.run(WzkStartApp.class, args);
}
private final WzkDocumentRepo wzkDocumentRepo;
}

问题快速排查

症状与排查修复表

症状根因快排查方法修复方法
启动连不上URI/端口/库名/鉴权写错mongo --host localhost --port 37017修正 spring.data.mongodb.uri
Repo 报空指针实体无 @Id/泛型不匹配看实体与泛型@Id,泛型对齐
查慢无索引/条件不命中explain()totalDocsExamined加索引或改查询
事务失败单机非副本集rs.status()改为副本集/Testcontainers 配置
凭证泄漏URI 写在仓库看配置${MONGODB_URI:...} 环境变量

【知识补充】Template方式详解

1. 概念与原理

Template(模板)是一种设计模式,它通过定义算法的骨架来规范流程,同时允许子类在不改变算法结构的情况下重新定义某些步骤。这种模式属于行为型设计模式,主要用于解决在多个相似流程中重复代码的问题。

核心原理:

  • 父类定义算法框架(不可变部分)
  • 子类实现具体步骤(可变部分)
  • 通过抽象方法或钩子方法实现扩展点

2. 实现方式

2.1 类实现方式

public abstract class AbstractTemplate {
// 模板方法(final防止子类修改算法结构)
public final void templateMethod() {
step1();
step2();
if(hookMethod()) {
step3();
}
}
// 基本方法(抽象方法由子类实现)
protected abstract void step1();
protected abstract void step2();
// 钩子方法(提供默认实现)
protected boolean hookMethod() {
return true;
}
// 具体方法(通用实现)
private void step3() {
System.out.println("执行步骤3");
}
}

2.2 接口默认方法实现(Java 8+)

public interface Template {
default void templateMethod() {
step1();
step2();
if(hookMethod()) {
step3();
}
}
void step1();
void step2();
default boolean hookMethod() {
return true;
}
private void step3() {
System.out.println("执行步骤3");
}
}

3. 应用场景

3.1 典型应用

  1. 框架设计:如Spring的JdbcTemplate
  2. 业务流程:如订单处理流程
  3. 算法实现:如排序算法模板
  4. 文档生成:如报告生成器

3.2 具体示例

电商订单处理模板

public abstract class OrderProcessor {
public final void processOrder() {
validateOrder();
calculatePayment();
if(needsShipping()) {
arrangeShipping();
}
sendConfirmation();
}
protected abstract void validateOrder();
protected abstract void calculatePayment();
protected boolean needsShipping() {
return true;
}
private void arrangeShipping() {
// 物流安排实现
}
private void sendConfirmation() {
// 发送确认邮件/短信
}
}

4. 优缺点分析

优点:

  1. 代码复用:将不变行为搬到父类,避免重复代码
  2. 扩展性好:通过子类扩展新的行为,符合开闭原则
  3. 便于维护:算法结构清晰,修改只需调整模板方法
  4. 控制反转:由父类控制流程,子类只需关注实现细节

缺点:

  1. 类数量增加:每个具体实现都需要一个子类
  2. 设计复杂度:需要合理划分可变和不可变部分
  3. 继承限制:Java单继承机制会限制使用场景

5. 最佳实践

  1. 合理使用钩子方法:为可选步骤提供灵活的扩展点
  2. 控制模板方法复杂度:避免创建过于复杂的模板方法
  3. 命名规范
    • 模板方法使用"template"前缀
    • 钩子方法使用"hook"或"can"前缀
  4. 文档说明:明确标注哪些方法是必须实现的,哪些是可选的

6. 与其他模式的关系

  1. 与策略模式

    • Template使用继承
    • Strategy使用组合
    • Template强调算法步骤,Strategy强调算法替换
  2. 与工厂方法模式

    • 工厂方法常作为模板方法的一步实现
  3. 与建造者模式

    • 都用于分步构建对象
    • Template强调步骤顺序,Builder强调创建过程

7. 扩展应用

7.1 回调方式的模板模式

public class TemplateWithCallback {
public void execute(Callback callback) {
preProcess();
callback.doOperation();
postProcess();
}
private void preProcess() {
// 预处理逻辑
}
private void postProcess() {
// 后处理逻辑
}
public interface Callback {
void doOperation();
}
}

7.2 函数式编程实现

public class FunctionalTemplate {
public void execute(Runnable preProcess,
Runnable operation,
Runnable postProcess) {
preProcess.run();
operation.run();
postProcess.run();
}
}

其他系列

AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈
AI模块直达链接

Java篇持续更新中(长期更新)

Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
Java模块直达链接

大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
大数据模块直达链接

posted @ 2025-11-20 21:03  clnchanpin  阅读(17)  评论(0)    收藏  举报