mongotemplate 连接 mongodb 需确保 spring-boot-starter-data-mongodb 与 spring boot 版本兼容,配置 uri(如 mongodb://localhost:27017/mydb),注意 tls 和认证;save() 先查后更或插,insert() 强制插入;查询需注意字段类型匹配、正确使用 .is() 和嵌套路径;删除前应验证 query 是否命中,避免误删。

Spring Boot 里 MongoTemplate 怎么连上 MongoDB?
连不上基本是配置或依赖没对齐。先确认 spring-boot-starter-data-mongodb 版本和 Spring Boot 主版本兼容——比如 Boot 3.x 必须用 Spring Data MongoDB 4.x,否则 MongoTemplate 初始化失败,报 BeanCreationException: Error creating bean with name 'mongoTemplate'。
关键配置项必须写在 application.yml 里:
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
别用 host/port/database 拆开写,URI 方式最稳;如果用了认证,URI 要带用户名密码,比如 mongodb://user:pass@localhost:27017/mydb。Spring Boot 3.2+ 默认禁用旧版连接池,不加 ?tls=false 在本地测试时可能卡住。
save() 和 insert() 有什么区别?
不是“都能存”,而是语义和行为完全不同:save() 会先查 _id,存在就 $set 全量更新(覆盖),不存在才插入;insert() 强制插入,_id 冲突直接抛 DuplicateKeyException。
常见踩坑点:
- 用
save()更新部分字段却意外清空了其他字段(因为传的是新对象,没设的字段变成 null) - 用
insert()批量写入但忘了给每个对象生成唯一_id,结果崩在第二条 - 想原子更新数值字段(如计数器)却用了
save(),导致并发写丢失
正确做法:只用 save() 做「有则更新、无则新建」;确定要插入才用 insert();改单个字段优先走 updateFirst() + Update.update()。
查文档时 Query.query(Criteria.where("status")) 为什么查不到?
多半是字段类型不匹配或查询条件写错。MongoDB 对字符串、数字、布尔值严格区分,Java 里传 "1" 查不到数据库里存的数字 1;同理,true 不等于 "true"。
调试建议:
- 用
mongo shell或 Compass 先确认目标文档真实字段名和值类型 - 查字符串记得加
.is("xxx"),别只写where("status")—— 这等价于{ status: { $exists: true } },不是等于 - 查嵌套字段用点号路径,比如
where("address.city").is("Beijing"),别写成where("address").where("city") - 时间范围查询务必转成
Instant或Date,别传字符串,否则索引失效
删除操作后数据还在,是 remove() 没生效?
大概率是 Query 条件没命中任何文档,而 remove() 默认不报错。它返回一个 DeleteResult,里面 getDeletedCount() 是 0 就说明删了个寂寞。
安全做法:
- 删之前先用同样
Queryfind()一下,确认能查到 - 生产环境避免用
remove(new Query())清空集合,改用mongoTemplate.getCollection("xxx").drop()更明确 - 软删除比物理删除更常用,别在实体类里加
@Document就以为自动支持逻辑删——得自己加deletedAt字段并统一拦截查询条件
另外,remove() 只删匹配的第一条(removeFirst())或全部(removeMulti()),名字不带 Multi 却想删多条?那肯定漏了。










