资讯动态

Windows下MongoDB安装与Spring Boot集成实战指南

发布时间:2026/10/22 3:06:20 来源:尧图企业网站定制
1. Windows 环境下的 MongoDB 安装准备1.1 为什么 Java 开发者需要 MongoDB写 Java 的服务端程序关系型数据库 MySQL、PostgreSQL 用得最多这没毛病。但碰到一些特殊场景比如日志收集、用户行为埋点、商品评论、配置中心用关系型数据库反而别扭——表结构要提前设计、字段要严格对齐、扩展字段要写迁移脚本改一次表结构就像动一次手术。MongoDB 作为文档型数据库的代表存储的是 BSON 格式二进制 JSON每条记录就是一个文档字段随意增减嵌套结构直接存。这就意味着你不需要预先定义表结构业务变了直接加字段代码里怎么写库里就怎么存。Java 开发者上手 MongoDB 的成本其实很低因为你可以把 MongoDB 里的一个文档直接理解成一个 Map或者一个没有类型约束的 POJO。这篇文章讲的是一条完整的链路从 Windows 下的 MongoDB 安装、基础配置到常用的命令行操作再一步步接入 Spring Boot最终跑通一个可用的数据访问接口。我尽量把每一步的坑都标注出来尤其是 Windows 特有的问题——权限、服务注册、路径分隔符这些东西在 macOS 和 Linux 上从来不是事但在 Windows 上能卡你半小时。1.2 安装前的版本选型和规划先说版本。MongoDB 的版本号从 4.x 一路走到 7.x目前生产环境用得比较多的是 6.0 和 7.0。我自己的建议是本地开发直接装最新的稳定版写这篇文章时是 7.0.x因为新版本的查询引擎和聚合管道的性能优化很明显。如果你是为了对齐公司生产环境那就先确认生产环境的版本本地装成一致的避免本地跑得好好的上线就出兼容性问题。另一个要注意的是 MongoDB 的许可证问题。MongoDB 从 4.4 版本开始采用了 SSPL 许可证对云服务商限制比较多但如果你是本地开发、企业内部使用完全没有影响。别被网上的讨论吓到个人开发者和企业自用都是没问题的。安装包选择方面MongoDB 官方提供了两种形式MSI 安装包图形界面引导帮你配好 Windows 服务适合新手和日常开发。ZIP 压缩包解压即用适合想完全掌控目录结构的人也适合做绿色版工具。我用的是 MSI 安装包因为安装过程会顺手把 MongoDB 注册成 Windows 服务这样开机自启、后台运行都比较省心。如果你用 ZIP 包每次开机都要手动启动 mongod 进程偶尔忘了还挺耽误事。2. 从下载到启动完整安装流程2.1 下载安装包与安装步骤打开 MongoDB 官网的下载页面选择 MongoDB Community ServerWindows 平台MSI 格式。下载的时候留意一下页面上的版本号建议下载最新的稳定版。安装包大概一百多 MB速度取决于网络情况。下载完成后双击运行安装过程中有几个关键选项需要仔细处理第一个是安装类型。新手直接选 Complete省心。但如果你想自定义数据目录和日志目录的位置选 Custom把安装路径改到非系统盘比如 D:\MongoDB\Server\7.0。这么做的好处是系统盘空间不够时不会把数据库文件塞满 C 盘而且将来重装系统也不容易丢数据。第二个关键是Install MongoD as a Service这个勾选项。勾选之后安装程序会自动把 MongoDB 注册成 Windows 服务。旁边的Run service as Network Service user保持默认即可这是权限最小的账户足够 MongoDB 正常运行别改成 Local System权限过大的账号反而有安全风险。第三个是Install MongoDB Compass的选项。Compass 是官方出的图形化管理工具能看到数据库里的数据长什么样、能直接执行查询、还能看服务器的实时状态指标。安装包默认会勾选它我建议保留。刚开始用 MongoDB 的时候命令行 Compass 搭配着来效率会高很多。2.2 安装完成后的目录结构与关键配置安装完成后默认的安装目录是C:\Program Files\MongoDB\Server\7.0\里面的结构大概是这样的bin目录包含所有可执行文件核心的是mongod.exe服务端和mongosh.exe命令行客户端。data目录存放数据库文件的默认位置是C:\Program Files\MongoDB\Server\7.0\data\。但实际生产环境中我们通常会把数据目录改到独立磁盘上。log目录日志文件的存放位置。这里有个非常重要的点MongoDB 启动时如果找不到数据目录会直接报错退出但它不会自动创建目录。所以你需要手动创建好数据目录和日志目录或者干脆在配置文件里指定并确保目录存在。我在安装完成后做的第一件事就是修改 MongoDB 的配置文件。Windows 下 MSI 安装的默认配置文件在C:\Program Files\MongoDB\Server\7.0\bin\mongod.cfg内容长这样systemLog: destination: file path: C:\Program Files\MongoDB\Server\7.0\log\mongod.log logAppend: true storage: dbPath: C:\Program Files\MongoDB\Server\7.0\data net: bindIp: 127.0.0.1 port: 27017这个配置文件用的是 YAML 格式每一项都对应启动参数。比如net.port指定端口默认 27017net.bindIp指定绑定的 IP 地址。默认只绑定127.0.0.1也就是只有本机能访问这个配置对本地开发来说很安全。如果你想让同一局域网的其他机器也能连接需要把 bindIp 改成0.0.0.0但前提是你已经配置了用户认证否则裸奔在局域网里非常危险。2.3 启动服务与验证环境安装完成且配置就绪后打开 Windows 服务管理器Win R输入services.msc找到 MongoDB Server 相关的服务在最新版中服务名是 MongoDB Server (MongoDB)右键点击启动。如果启动失败大概率是配置文件里的路径有问题或者目录不存在。验证是否启动成功最简单的方式是在命令行里执行mongosh看到提示符变成test就说明连接成功了此时 MongoDB 正在27017端口上监听。如果你想确认端口的状态可以执行netstat -an | findstr 27017看到TCP 127.0.0.1:27017 0.0.0.0:0 LISTENING这条就说明一切正常。这里提醒一个 Windows 特有的坑如果你修改了 mongod.cfg 文件重启服务的正确方式是先net stop MongoDB再net start MongoDB或者用sc.exe命令。不要直接关掉命令行窗口那只杀掉当前前台进程服务还在后台运行。还有Windows 服务的方式启动 MongoDB 时配置文件里的systemLog.path指定的日志目录必须存在否则服务会起不来。这个问题我第一次装的时候踩过日志里报的错是Cannot open log file排查了半天才发现是 log 目录没创建。3. MongoDB 基础使用命令行操作与核心概念3.1 库、集合、文档和关系型数据库对照理解MongoDB 里有三个核心概念数据库Database、集合Collection、文档Document。用关系型数据库的视角来看数据库对数据库。集合对应表Table。文档对应行Row。但对应关系只是形式上的本质区别在于集合不强制文档结构统一。同一个集合里一个文档是{name: 张三, age: 25}另一个文档可以是{title: Java开发, tags: [后端, Spring]}这在 MongoDB 里完全合法。这种设计带来的直接好处是业务模型变化时不需要执行 ALTER TABLE。比如你要给用户增加一个phone字段关系型数据库要ALTER TABLE user ADD COLUMN phone VARCHAR(20)还得考虑存量数据的默认值MongoDB 这边直接写入带phone字段的文档就行老文档没有这个字段也不影响查询。当然自由是要付出代价的。正因为结构不强制统一你在 Java 代码里读取文档时字段缺失、类型不匹配的问题就需要自己兜底。这也是为什么现在很多团队给 MongoDB 文档加一层 schema 校验Validator或者依赖 Spring Data MongoDB 里自定义转换器的能力。3.2 日常开发必会的增删改查命令启动mongosh之后使用命令前先切换到目标数据库use blogdbuse命令在 MongoDB 里有个特殊行为如果数据库不存在它不会立即创建而是等你写入第一条数据时才真正创建。这个设计很实用避免了一堆空壳数据库。插入一条文档db.users.insertOne( { name: 张三, age: 28, skills: [Java, Spring Boot, MySQL], address: { city: 北京, street: 中关村 } } )insertOne插入单条文档insertMany批量插入。注意 MongoDB 会自动给每个文档加上_id字段默认是 ObjectId 类型的 24 位十六进制字符串你不需要自己生成。查询文档db.users.find({ age: { $gt: 25 } })$gt是大于的意思类似的还有$lt小于、$gte大于等于、$lte小于等于、$ne不等于。如果查询条件要匹配嵌套字段直接用点号db.users.find({ address.city: 北京 })更新文档db.users.updateOne( { name: 张三 }, { $set: { age: 29 } } )这里有一个高频误操作updateOne的第二个参数如果不加$set直接写{ age: 29 }那么整个文档会被替换成只有age这一个字段其他字段全部丢失。我在公司带新人时见过不下三次这种操作把线上数据改没了。删除文档db.users.deleteOne({ name: 张三 })如果条件不加deleteMany({})会清空整个集合这个操作没有类似关系型数据库的事务保护执行之前一定要确认条件。3.3 索引查询加速的必经之路MongoDB 的索引机制和 MySQL 类似但创建语法和索引类型有一些差别。字段数据量小的时候有没有索引无所谓但到了几十万条以上不带索引的查询就可能出现秒级延迟。创建单字段索引db.users.createIndex({ name: 1 })创建复合索引db.users.createIndex({ age: 1, name: -1 })1表示升序-1表示降序。复合索引的字段顺序是有讲究的一般把等值查询字段放前面范围查询字段放后面。比如按城市查、再按年龄排序那么{ address.city: 1, age: -1 }这个索引顺序更合理。MongoDB 还有一个比较特色的索引类型叫 TTL 索引专门用于自动过期删除。比如日志数据只保留 30 天可以这样db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })MongoDB 后台会定期扫描这个字段超过 30 天的数据自动删除。这个机制做定时清理任务非常方便省掉了写 Cron 任务的心智负担。4. Spring Boot 集成从依赖到首个接口4.1 引入依赖与配置数据源Spring Boot 集成 MongoDB 的核心依赖是spring-boot-starter-data-mongodb。如果是 Maven 项目加这一段dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-mongodb/artifactId /dependency这个 starter 会自动装配MongoTemplate和MongoRepository相关的组件不需要你手动创建连接工厂。然后在application.yml里配置连接信息spring: data: mongodb: uri: mongodb://localhost:27017/blogdb注意这里是spring.data.mongodb.uri不是spring.mongodb.uri版本不同配置路径有差异。如果你用的是 Spring Boot 2.x可能有spring.data.mongodb.host和port这种老式配置但 2.4 之后的版本更推荐直接用uri统一配置。这个差异很容易踩坑配置了不生效或者报连接失败时先检查一下是不是路径写错了。有用户名密码的配置形式是这样的spring: data: mongodb: uri: mongodb://username:passwordlocalhost:27017/blogdb?authSourceadminauthSourceadmin的意思是认证时去 admin 库校验用户的身份这个参数在开启 MongoDB 认证后是必须的。4.2 实体类与 RepositorySpring Data MongoDB 的编程模型和 Spring Data JPA 高度相似。一个实体类对应一个集合字段映射通过注解来配置。先定义一个实体类Data Document(collection users) public class User { Id private String id; private String name; private Integer age; private ListString skills; private Address address; Data public static class Address { private String city; private String street; } }Document注解声明这个类对应 MongoDB 里的users集合。Id标记主键字段类型用 String 就行Spring Data 会自动把 MongoDB 的 ObjectId 转成字符串省去了手动转换的麻烦。定义 Repository 接口public interface UserRepository extends MongoRepositoryUser, String { ListUser findByName(String name); ListUser findByAgeGreaterThan(Integer age); ListUser findByAddressCity(String city); }这里你会发现Spring Data MongoDB 的查询方法命名规则和 Spring Data JPA 完全一致findByName、findByAgeGreaterThan、findByAddressCity这些方法名会被自动解析成对应的查询语句。findByAddressCity这种嵌套字段的写法也能正常工作Spring Data 会帮你处理好点号路径。这种查询方式胜在快适合简单的场景。但碰到复杂的条件组合、聚合操作时方法名就表达不了了这时候要用MongoTemplate。4.3 使用 MongoTemplate 处理复杂查询MongoTemplate是 Spring Data MongoDB 提供的最底层的操作模板相当于 JdbcTemplate 在关系型数据库中的地位。它能做 Repository 做不了的复杂查询。注入方式很简单Service public class UserService { Autowired private MongoTemplate mongoTemplate; }举个例子查询年龄在 25 到 30 之间、并且技能列表里包含 Java 的用户同时按年龄降序排列public ListUser queryUsers() { Query query new Query(); Criteria criteria new Criteria(); criteria.and(age).gte(25).lte(30); criteria.and(skills).in(Java); query.addCriteria(criteria); query.with(Sort.by(Sort.Direction.DESC, age)); return mongoTemplate.find(query, User.class); }Criteria对象就是用来构建查询条件的对应的 JSON 查询语句是{ age: { $gte: 25, $lte: 30 }, skills: { $in: [Java] } }聚合操作也是MongoTemplate的重头戏。比如按城市分组统计用户数量public ListMapString, Object countByCity() { Aggregation agg Aggregation.newAggregation( Aggregation.group(address.city).count().as(total) ); AggregationResultsMap results mongoTemplate.aggregate(agg, users, Map.class); return results.getMappedResults(); }从我的实践经验来看简单的 CRUD 用 Repository涉及条件组合、排序分页、聚合统计时用 MongoTemplate这样的分工最清晰。4.4 写一个完整的 CRUD 接口到这里把前面的东西串起来写一个完整的 RESTful 接口。Controller 层负责 HTTP 入口Service 层处理业务逻辑Repository 层做数据访问。RestController RequestMapping(/api/users) public class UserController { Autowired private UserRepository userRepository; PostMapping public User createUser(RequestBody User user) { return userRepository.save(user); } GetMapping(/{id}) public User getUser(PathVariable String id) { return userRepository.findById(id).orElseThrow( () - new RuntimeException(User not found) ); } GetMapping public ListUser listUsers(RequestParam(required false) Integer age) { if (age null) { return userRepository.findAll(); } return userRepository.findByAgeGreaterThan(age); } PutMapping(/{id}) public User updateUser(PathVariable String id, RequestBody User user) { user.setId(id); return userRepository.save(user); } DeleteMapping(/{id}) public void deleteUser(PathVariable String id) { userRepository.deleteById(id); } }save方法是个 upsert 操作如果传入的对象带id就更新不带就插入。所以更新场景下记得把路径里的 id 塞进对象里再 save避免产生了一条新记录。Controller 层可以跑起来了启动 Spring Boot 应用用 Postman 或者 curl 试一下curl -X POST http://localhost:8080/api/users \ -H Content-Type: application/json \ -d {\name\:\李四\,\age\:26,\skills\:[\Python\,\Golang\],\address\:{\city\:\上海\,\street\:\陆家嘴\}}返回的 JSON 里id字段会被自动填充上 MongoDB 的 ObjectId 字符串这就是新文档在数据库里的唯一标识。5. 进阶话题事务、备份与性能调优5.1 事务支持与使用前提很多 Java 开发者习惯性地认为 MongoDB 不支持事务这个印象过时了。从 4.0 版本开始MongoDB 引入了多文档事务支持在副本集Replica Set模式下可以使用。单机部署的 MongoDB 默认不是副本集但 MongoDB 7.0 允许在单机模式下测试事务功能。Spring 里的Transactional注解可以直接用于 MongoDB 操作Transactional public void transferMoney(String fromUserId, String toUserId, int amount) { // 扣减 fromUserId 的余额 // 增加 toUserId 的余额 }这个过程中任何一个操作失败整个事务都会回滚保证数据的一致性。事务的隔离级别方面MongoDB 默认提供的是快照隔离性能和一致性之间的平衡做得还可以。但要注意两点事务里的操作要在合理时间内完成事务持续时间越长冲突的概率越高另一个是事务会占用额外的存储空间WiredTiger 引擎的 undolog所以别把无关紧要的操作随便塞进事务。5.2 数据备份与恢复必须养成的习惯本地开发环境的数据可能不太值钱但生产环境的数据就是命。至少要有能力做备份和恢复。MongoDB 官方的备份工具是mongodump和mongorestore。在 bin 目录下和你启动服务用的mongod在一个地方。备份整个数据库mongodump --host localhost:27017 --db blogdb --out D:\backup\mongodb\20250101这条命令会把 blogdb 库的所有集合导出到D:\backup\mongodb\20250101\blogdb目录下每个集合生成一个.bson文件和一个.metadata.json文件。恢复数据mongorestore --host localhost:27017 --db blogdb --drop D:\backup\mongodb\20250101\blogdb--drop参数表示在恢复前删除原有的集合避免新旧数据混在一起。不太确定目标库状态的情况下别加这个参数默认是追加写入。我自己一般在两种情况下强制自己跑一次备份一是大的数据结构调整前二是升级 MongoDB 版本前。这两件事出了岔子有备份在手就能兜底否则只能干瞪眼。5.3 性能问题定位的三个手段MongoDB 在开发环境很少出性能问题但数据量上来之后慢查询就会冒出来。定位手段优先级如下第一个是查看慢查询日志。MongoDB 默认会记录执行时间超过 100ms 的查询到日志文件里。也可以在 mongosh 里动态修改阈值db.setProfilingLevel(1, { slowms: 50 })这样所有超过 50ms 的操作都会记录到system.profile集合里用db.system.profile.find().sort({ ts: -1 }).limit(20)就能看到最近的慢操作。第二个是explain函数分析查询执行计划db.users.find({ age: { $gt: 25 } }).explain(executionStats)重点看winningPlan和totalKeysExamined、totalDocsExamined这几个字段。如果totalKeysExamined很大但totalDocsExamined很小说明索引选择可能有问题或者索引覆盖度不够。如果totalDocsExamined和返回的文档数差距极大大概率是全集合扫描了这个时候创建索引是第一要务。第三个是 MongoDB Compass 自带的性能面板。能实时看到操作命令的分布、读写速率、连接数比命令行直观很多。遇到拖垮数据库的慢操作时这个面板能快速锁定问题来源。6. Windows 环境下的坑与解决方案汇总6.1 服务启动失败排查清单Windows 上 MongoDB 服务起不来原因基本集中在以下几类第一类是配置文件错误。YAML 格式要求严格路径里的冒号后面必须有空格否则解析直接失败。另外dbPath指向的目录必须存在MongoDB 不会自己创建。第二类是端口被占用。执行netstat -ano | findstr 27017看有没有其他进程占着这个端口。如果被占用了要么改 MongoDB 的端口要么停掉占用进程。第三类是权限问题。如果 MongoDB 服务配置运行的账户没有数据目录的写权限进程会直接闪退。解决方案是给数据目录加上 Users 组的写入权限或者把服务改成用当前用户运行不推荐但本地开发可以凑合。排查步骤就是先看 Windows 事件查看器里的应用程序日志或者直接去 mongod.log 里看最后几行报错信息。日志里写明了具体的失败原因比盲猜快得多。6.2 常见连接错误与解决方法错误一MongoTimeoutException / Connect Timeout连接超时原因要么是 MongoDB 服务没启动要么是端口不通要么是绑定的 IP 不允许该来源访问。检查顺序服务状态、端口监听状态、bindIp 配置。错误二Authentication failed认证失败用户名密码不对或者authSource指向了错误的库。MongoDB 创建用户时要指定认证库连接字符串里也要带上对应的库。错误三读取到的字段值为 nullJava 代码里实体类的字段名和 MongoDB 文档里的字段名对不上。MongoDB 默认保留你写入时的字段名Spring Data 的命名策略默认是驼峰转下划线如果文档里是user_name实体类里是userName需要加Field(user_name)注解。6.3 安全建议与生产意识本地开发环境虽然不直接暴露到公网但一些安全习惯最好从一开始就建立。首先是开启访问认证。MongoDB 默认是不需要账号密码就能连接的这在本地没什么问题但如果你的机器开了防火墙端口转发或者在公司内网这个风险就存在了。设置认证的步骤是先创建一个管理员用户use admin db.createUser( { user: admin, pwd: your_password, roles: [root] } )然后在配置文件里开启认证security: authorization: enabled重启服务后续连接就必须带用户名密码了。这个时候 Compass 连接也需要输入凭据Spring Boot 的连接 URI 也要相应加上账号密码。其次是防火墙配置。Windows 的防火墙如果开启了外部机器是没法直接访问 MongoDB 默认 27017 端口的这本身就是一层保护。如果你确实需要让别的机器访问才需要去防火墙里添加入站规则否则保持默认就行。7. 从零到一完整的开发流程演示7.1 一个用户管理页面的前后端串联这篇内容不光是讲安装和接口我更想带着你跑通一个完整的场景把前面所有知识点串起来。假设现在要做一个小型博客系统的用户管理模块前端页面有两个功能展示用户列表、新增用户。后端就用前面写的UserController里的GET /api/users和POST /api/users两个接口。跑通这个流程需要三步准备第一步启动 MongoDB 服务Windows 服务已注册的话开机就是跑着的不用额外操作。第二步启动我们的 Spring Boot 应用确认控制台输出的启动日志里没有报错并且 MongoDB 连接成功。第三步用 Compass 手动往blogdb库里的users集合插入几条测试数据db.users.insertMany([ { name: 王五, age: 30, skills: [Java, Linux], address: { city: 深圳, street: 科技园 } }, { name: 赵六, age: 22, skills: [JavaScript, Vue], address: { city: 杭州, street: 西湖区 } }, { name: 钱七, age: 35, skills: [Java, Docker], address: { city: 北京, street: 上地 } } ])然后前端调用GET /api/users?age25接口就会走findByAgeGreaterThan(25)这条查询返回你这三条数据年龄都大于 25 了。前端拿到 JSON 数组渲染列表点提交按钮调POST /api/users保存新用户新数据存进去之后再次刷新列表就能看到。7.2 实际运行中的体会这个流程跑通之后你应该能感觉到 MongoDB 和关系型数据库在开发效率上的差异。整个过程中不需要写建表语句不需要改表结构前端传入的 JSON 结构直接入库后端的返回结果也几乎不用做字段映射。一个 Java 类对应一个集合一个 JSON 对象对应一个文档心智负担小很多。但我也想说句实话MongoDB 适合用的场景是数据模型灵活、读写要求高、字段会频繁变化的业务。如果你的业务强依赖多表关联、复杂的 ACID 约束那还是老老实实选关系型数据库。没有银弹只有合适。8. 写在最后关于 Windows 下 MongoDB 的安装和 Spring Boot 集成核心的内容到这里已经全部覆盖了。从安装配置、命令行操作、Spring Data 编程模型到事务、备份、性能分析和常见问题的排查这条链路是我自己在实际开发中反复走过的路线希望对你也有帮助。最后再分享一个小技巧Windows 上配好了 MongoDB 环境和 Spring Boot 集成模板之后建议把整个配置过程整理成一份笔记包括下载版本的记录、绑定端口、数据目录路径、认证信息。因为 MongoDB 的升级频率不低半年后你再想装一个新版本翻这份笔记能省很多重新摸索的时间。在实际项目中我把这套环境从 4.2 版本一直用到 7.0每次升级都比较顺滑踩过的坑基本都集中在 Windows 服务的配置细节上。如果你在安装或集成过程中遇到什么奇怪的问题优先检查日志日志里大多有明确的线索。实在解决不了就去官方文档或者社区里搜一搜具体报错信息基本都能找到答案。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑