前阵子有朋友问我java整合MongoDB方面的问题,之前也没用java整合过MongoDB,顺便研究下,在此记录下来
MongoDB 简介
- MongoDB 是一个基于分布式文件存储的数据库,由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
- MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
- MongoDB 将数据存储在类似JSON的灵活文档中,这意味着字段可能因文档而异,并且数据结构可能会随时间而变化
- 文档模型映射到应用程序代码中的对象,使数据易于使用
- 即席查询,索引和实时聚合提供了访问和分析数据的强大方法
还没接触过MongoDB的小伙伴,可以去看看我之前写的文章 MongoDB学习笔记(增删改查、聚合、索引、连接、备份与恢复、监控等)
运行环境
IntelliJ IDEA 2017
JDK 1.8
Spring Boot 2.1
maven 4.0.0
项目结构
添加Spring Boot和MongoDB依赖。
1 | <dependency> |
application.properties
1 | # IP地址 |
编写User实体
1 | package com.example.mongodemo.model; |
注:此处实体类使用的@Data、@NoArgsConstructor、@AllArgsConstructor
注解,分别表示自动生成该实体类字段的get/set/toString/equals/hashCode方法、无参构造,有参构造。此为idea使用lombok插件,方法自行百度,此处不累赘。
编写UserRepository
通过继承MongoRepository接口,我们可以非常方便地实现对一个对象的增删改查,要使用Repository的功能,先继承MongoRepository<T, TD>接口,其中T为仓库保存的bean类
,TD为该bean的唯一标识的类型
,一般为ObjectId。之后在service中注入该接口就可以使用,无需实现里面的方法,spring会根据定义的规则自动生成。
但是MongoRepository实现了的只是最基本的增删改查的功能,要想增加额外的查询方法,可以按照以下规则定义接口的方法。自定义查询方法,格式为“findBy+字段名+方法后缀”
,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象,返回Page集合。
1 | package com.example.mongodemo.dao; |
编写测试类
添加测试数据
1 | package com.example.mongodemo; |
运行结果:
打开Navicat查看:
删除
1 |
|
运行结果:
总数变为16
条件查询
1 |
|
运行结果:
可以看到8条集合,数据超出部分就不贴图了
自定义查询
1 |
|
运行结果:
遇到的一些坑
findOne和findById
因为这次我用的Spring Boot版本是2.1,之前是1.4.1。改版之后将findOne 更名为 findById,但是findById并不仅仅是将findOne改名,它返回的对象变成了Optional。如果想让findById和findOne有同样的功能,可以用下面这个函数:1
User u = userRepository.findById(1L).orElse(null);
insert()和save()
insert:当主键”_id”在集合中存在时,不做任何处理。 将会抛以下异常:1
org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection
save:当主键”_id”在集合中存在时,进行更新。 数据整体都会更新 ,新数据会替换掉原数据 ID 以外的所有数据。如ID 不存在就新增一条数据
来看看 MongoRepository 接口的具体实现类SimpleMongoRepository<T, ID extends Serializable>
的save 方法到底怎么写的。
判断一下主键的值是否存在,存在返回false,存正为true.通过 处理类 设置主键Id的,就会走save,而不是insert了