SpringBoot | 第三十一章:MongoDB的集成和使用
前言
上一章节,简单讲解了如何集成
Spring-data-jpa
。本章节,我们来看看如何集成NoSQL
的Mongodb
。mongodb
是最早热门非关系数据库的之一,使用也比较普遍。最适合来存储一些非结构数据了,适合对大量或者无固定格式的数据进行存储,比如:日志、缓存等。
一点知识
以下部分关于Mongodb
介绍,来自网站:https://www.mongodb.com/cn 、纯洁的微笑
MongoDB简介
MongoDB
(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。作为一个适用于敏捷开发的数据库,MongoDB
的数据模式可以随着应用程序的发展而灵活地更新。与此同时,它也为开发人员 提供了传统数据库的功能:二级索引,完整的查询系统以及严格一致性等等。 MongoDB
能够使企业更加具有敏捷性和可扩展性,各种规模的企业都可以通过使用MongoDB来创建新的应用,提高与客户之间的工作效率,加快产品上市时间,以及降低企业成本。
MongoDB
是专为可扩展性,高性能和高可用性而设计的数据库。它可以从单服务器部署扩展到大型、复杂的多数据中心架构。利用内存计算的优势,MongoDB
能够提供高性能的数据读写操作。 MongoDB
的本地复制和自动故障转移功能使您的应用程序具有企业级的可靠性和操作灵活性。
简单来说,MongoDB
是一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库之间的产品,其主要目标是在键/值存储方式(提供了高性能和高度伸缩性)和传统的RDBMS系统(具有丰富的功能)之间架起一座桥梁,它集两者的优势于一身。
MongoDB
支持的数据结构非常松散,是类似json
的bson格式,因此可以存储比较复杂的数据类型,也因为他的存储格式也使得它所存储的数据在Nodejs程序应用中使用非常流畅。
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。
MongoDB
中的一条记录就是一个文档,是一个数据结构,由字段和值对组成。MongoDB文档与JSON对象类似。字段的值有可能包括其它文档、数组以及文档数组。MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。
MongoDB的适合对大量或者无固定格式的数据进行存储,比如:日志、缓存等。对事物支持较弱,不适用复杂的多文档(多表)的级联查询。
SpringBoot集成MongoDB
得力于
SpringBoot
方便性,集成MongoDB
也是很简单的。可通过三种方式进行访问,分别是:原生Db对象
、MongoTemplate
以及MongoRepository
。原生的方式需要连接其语法规则,这里就不阐述了,毕竟不熟悉。还是使用封装好的吧,开箱急用!
准备工作
本文示例的MongoDB版本为:4.0.3。
可视化工具为:studio-3t-x64。
至于MongoDB
如何安装,大家简单百度下就好了,很简单。下载个msi
,直接安装即可。
下载地址:https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-4.0.3-signed.msi
0.加入POM依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1.创建实体。
/**
* 通知消息对象
* @author oKong
*
*/
@Document(collection="notify_msg")//集合名
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NotifyMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = -8985545025018238754L;
@Id
String id;
/**
* 消息类型
*/
@Indexed
String notifyType;
/**
* 消息单号
*/
@Indexed
String notifyNo;
/**
* 消息通知日期
*/
String notifyDate;
/**
* 消息体
*/
@Field("notifyMsg")//可指定存储时的字段名
String notifyMsg;
/**
* 创建时间
*/
@CreatedDate
Date gmtCreate;
}
这里注意:@Document(collection="notify_msg") 表示:操作的集合为:notify_msg
。
这个可手动使用工具创建下。
另外,针对@CreatedDate
注解,也和之前的jpa
用法一直,创建时会自动赋值,需要在启动类中添加@EnableMongoAuditing
注解使其生效!
同时,可使用@Field
注解,可指定存储的键值名称,默认就是类字段名。如设置@Field("notify_Msg")
后,效果如下:
2.配置文件中填写连接地址。
#mongodb
# 单机模式 mongodb://name:pass@ip:port/database
# 集群模式 mongodb://user:pwd@ip1:port1,ip2:port2/database
spring.data.mongodb.uri=mongodb://127.0.0.1:27017/learning
注意,这里填写格式
- 单机模式:mongodb://name:pwd@ip:port/database
- 集群模式:mongodb://name:pwd@ip1:port1,ip2:port2/database
3.启动类编写。
/**
* mongodb 集成示例
* @author oKong
*
*/
@SpringBootApplication
@EnableMongoAuditing
//@EnableMongoRepositories(basePackages="cn.lqdev")//当有些dao不在default page下时 可通过此方法进行注册扫描包
@Slf4j
public class MongodbApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(MongodbApplication.class, args);
log.info("spring-boot-mongodb-chapter31启动!");
}
}
注意:当使用MongoRepositories
时,可能有些MongoRepositories
类不在默认的包路径(启动类路径)下,可使用@EnableMongoRepositories
的basePackages
需要扫描的路径信息。若都在默认的包路径下,可以不加此注解的。
MongoTemplate方式
以下示例下
MongoTemplate
方式进行数据操作。
0.创建一个接口类:
/**
* 接口服务
* @author oKong
*
*/
public interface NotifyMsgService {
/**
* 保存数据
* @author 作者:oKong
*/
NotifyMsg saveNotifyMsg(NotifyMsg msg);
/**
* 根据消息号查找
* @author 作者:oKong
*/
NotifyMsg findNotifyMsgByNo(String notifyNo);
/**
* 根据消息日期查找
* @author 作者:oKong
*/
List<NotifyMsg> findNotifyMsgByDate(String notifyDate);
/**
* 根据id进行删除 返回删除的对象
* @author 作者:oKong
*/
NotifyMsg delNotifyMsgById(String id);
}
1.接口实现类,引入MongoTemplate
。
/**
* MongoTemplate 访问实现
* @author oKong
*
*/
@Service
public class NotifyMsgServiceImpl implements NotifyMsgService{
@Autowired
MongoTemplate mongoTemplate;
@Override
public NotifyMsg saveNotifyMsg(NotifyMsg msg) {
//使用 save和insert都可以进行插入
//区别:当存在"_id"时
//insert 插入已经存在的id时 会异常
//save 则会进行更新
//简单来说 save 就是不存在插入 存在更新
mongoTemplate.insert(msg);
mongoTemplate.save(msg);
return msg;
}
@Override
public NotifyMsg findNotifyMsgByNo(String notifyNo) {
//根据Criteria 改造查询条件
Query query = new Query(Criteria.where("notifyNo").is(notifyNo));
return mongoTemplate.findOne(query, NotifyMsg.class);
}
@Override
public List<NotifyMsg> findNotifyMsgByDate(String notifyDate) {
//查找 notifyDate 根据Criteria 改造查询条件
Query query = new Query(Criteria.where("notifyDate").is(notifyDate));
return mongoTemplate.find(query, NotifyMsg.class);
}
@Override
public NotifyMsg delNotifyMsgById(String id) {
//查找 id 根据Criteria 改造查询条件
Query query = new Query(Criteria.where("id").is(id));
return mongoTemplate.findAndRemove(query, NotifyMsg.class);
}
}
针对查询,可以使用org.springframework.data.mongodb.core.query.Criteria
对象进行构造查询条件。其提供的方法如下:
具体使用时,可根据实际情况进行组合查询条件。
针对save
和insert
也需要注意下:
- 在无
_id
情况下,两者都能进行新增操作。 - 存在
_id
,同时记录库里不存在,两者都是进行插入操作。 - 存在
_id
,同时库里也存在记录,save
相当于进行更新操作。而insert
直接就异常了。
2.创建示例控制层。
/**
* mongoTemplate 示例
* @author oKong
*
*/
@RestController
@RequestMapping("/template")
@Slf4j
public class MongoTemplateController {
@Autowired
NotifyMsgService notifyMsgService;
@PostMapping("/add")
public NotifyMsg add(NotifyMsg msg) {
log.info("mongoTemplate方式新增:{}", msg);
return notifyMsgService.saveNotifyMsg(msg);
}
@PostMapping("del/{id}")
public NotifyMsg del(@PathVariable String id) {
log.info("mongoTemplate方式删除:{}", id);
return notifyMsgService.delNotifyMsgById(id);
}
@GetMapping("/find/{no}")
public NotifyMsg findNotifyMsgByNo(@PathVariable String no){
log.info("mongoTemplate方式查找:notifyNo-{}", no);
return notifyMsgService.findNotifyMsgByNo(no);
}
@GetMapping("/find/list/{date}")
public List<NotifyMsg> findNotifyMsgByDate(@PathVariable String date){
log.info("mongoTemplate方式查找:notifyDate-{}", date);
return notifyMsgService.findNotifyMsgByDate(date);
}
}
3.启动应用,使用Postman
进行访问。
可以看见,已经返回对应的信息,同时数据库也可看见记录了。
其他的都是类似的,大家可自行访问下:
- 根据日期返回列表信息:http://127.0.0.1:8080//template/find/list/具体日期
- 根据ID删除:http://127.0.0.1:8080/template/del/具体ID值
- 根据消息号查询:http://127.0.0.1:8080//template/find/具体消息号
MongoRepository方式
以上还需要自己编写一些类啥的,现在是
jpa
的方式进行操作数据,优雅,简单。
0.创建资源类
/**
* MongoRepository 示例
* @author oKong
*
*/
public interface NotifyMsgDao extends MongoRepository<NotifyMsg, String>{
/*
* 根据消息号进行查询
*/
NotifyMsg findByNotifyNo(String notifyNo);
/**
* 根据日期查询 自定义查询
* @author 作者:oKong
*/
//需要注意 查询的语法结构 ,同时这里和`jpa`不一样的地方是,第一个索引值从0 开始。。
@Query("{'notifyDate':?0}")
Page<NotifyMsg> queryBySql(String notifyDate,Pageable pageable);
}
这里需要注意一个地方:和上一章节的自定义sql不同之处是,参数索引值从0
开始。
同时,要注意查询的语法。具体用法,可查看:https://docs.spring.io/spring-data/mongodb/docs/1.10.14.RELEASE/reference/html/#mongodb.repositories.queries 这里简单截图下:
1.编写示例控制层。
/**
* MongoRepository 示例
* @author oKong
*
*/
@RestController
@RequestMapping("/repository")
@Slf4j
public class MongoRepositoryController {
@Autowired
NotifyMsgDao notifyMsgDao;
@PostMapping("/add")
public NotifyMsg add(NotifyMsg msg) {
log.info("repository方式新增:{}", msg);
return notifyMsgDao.save(msg);
}
@GetMapping("/find/sql/{date}")
public Page<NotifyMsg> queryBySql(@PathVariable String date){
Pageable pageable = new PageRequest(0, 10);
log.info("repository方式分页sql查找日期:{}", date);
return notifyMsgDao.queryBySql(date, pageable);
}
@GetMapping("/find/{no}")
public NotifyMsg findByNotifyNo(@PathVariable String no) {
log.info("repository方式查找单号:{}", no);
return notifyMsgDao.findByNotifyNo(no);
}
}
2.启动应用,使用Postman
,访问具体的方法,就可以看见相关结果了。
也可直接利用可视化工具,直接查看数据信息
参考资料
https://docs.spring.io/spring-data/mongodb/docs/1.10.14.RELEASE/reference/html
https://docs.spring.io/spring-boot/docs/1.5.15.RELEASE/reference/htmlsingle/#boot-features-mongodb
http://www.ityouknow.com/springboot/2017/05/08/springboot-mongodb.html
总结
本章节主要介绍了
Mongodb
的集成和简单的使用。相关更加详细的用法,可取官网查阅下,若使用MongoRepository
模式,基本和上章节讲的Spring-data-jpa
用法差不多,有些细微差别,就是自定义查询sql上了,毕竟一个是关系型数据库,一个是NoSql
数据库,查询的语法还有略有不同的。而使用MongoRepository
还是MongoTemplate
,就看个人喜好了。自从接触了jpa
后,是倾向于前者的,毕竟真的比较简单呀!想多复杂用法的大家自定查阅官网信息吧。
最后
目前互联网上很多大佬都有
SpringBoot
系列教程,如有雷同,请多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有所错误之处,还望提出,谢谢。
老生常谈
- 个人QQ:
499452441
- 微信公众号:
lqdevOps
个人博客:http://blog.lqdev.cn
完整示例:https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-31
原文地址:http://blog.lqdev.cn/2018/11/01/springboot/chapter-thirty-one/
SpringBoot | 第三十一章:MongoDB的集成和使用的更多相关文章
- Gradle 1.12用户指南翻译——第三十一章. FindBugs 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
- “全栈2019”Java多线程第三十一章:中断正在等待显式锁的线程
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- C#高级编程(第六版)学习:第三十一章:Windows窗体
第三十一章 Windows窗体 创建Windows窗体应用程序 在文本编辑器中输入: /* * form.cs * a simple windows form * */ using System; u ...
- “全栈2019”Java第三十一章:二维数组和多维数组详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 第三十一章、containers容器类部件QDockWidget停靠窗功能介绍
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...
- SpringBoot | 第三十三章:Spring web Servcies集成和使用
前言 最近有个单位内网系统需要对接统一门户,进行单点登录和待办事项对接功能.一般上政府系统都会要求做统一登录功能,这个没啥问题,反正业务系统都是做单点登录的,改下shiro相关类就好了.看了接入方案, ...
- SpringBoot | 第三十七章:集成Jasypt实现配置项加密
前言 近期在进行项目安全方面评审时,质量管理部门有提出需要对配置文件中的敏高文件进行加密处理,避免了信息泄露问题.想想前段时间某公司上传github时,把相应的生产数据库明文密码也一并上传了,导致了相 ...
- SpringBoot | 第三十章:Spring-data-jpa的集成和使用
前言 在前面的第九章:Mybatis-plus的集成和使用章节中,介绍了使用ORM框架mybatis-plus进行数据库的访问.今天,我们来简单学习下如何使用spring-data-jpa进行数据库的 ...
- springBoot系列教程02:mongodb的集成及使用
1.安装mongodb mongdb的安装很简单,只需要下载解压后运行mongod就好了 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86 ...
随机推荐
- IT职场中外企面试最爱提的问题
1.请介绍一下你自己. 这是外企常问的问题.一般人回答这个问题过于平常,只说姓名.年龄.爱好.工作经验,这些在简历上都有,其实,外企最希望知道的是求职者能否胜任工作,包括:最强的技能.最深入研究的知识 ...
- P3994 高速公路 树形DP+斜率优化+二分
$ \color{#0066ff}{ 题目描述 }$ C国拥有一张四通八达的高速公路网树,其中有n个城市,城市之间由一共n-1条高速公路连接.除了首都1号城市,每个城市都有一家本地的客运公司,可以发车 ...
- [Beta阶段]第一次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第一次Scrum Meeting 基本信息 名称 时间 地点 时长 第一次Scrum Meeting 19/04/29 大运村寝室6楼 70min ...
- Hibernate学习笔记(六)—— 查询优化
一.Hibernate的抓取策略 1.1 什么是抓取策略 抓取策略是当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略. HIbern ...
- RNA-Seq基因组比对工具HISAT2
原文网址: http://blog.biochen.com/archives/337 HISAT2是TopHat2/Bowti2的继任者,使用改进的BWT算法,实现了更快的速度和更少的资源占用,作者推 ...
- 查找表,Two Sum,15. 3Sum,18. 4Sum,16 3Sum Closest,149 Max points on line
Two Sum: 解法一:排序后使用双索引对撞:O(nlogn)+O(n) = O(nlogn) , 但是返回的是排序前的指针. 解法二:查找表.将所有元素放入查找表, 之后对于每一个元素a,查找 t ...
- CF D - Beautiful Graph(dfs 染色问题吧)给你一个图,每个节点可以赋值1,2,3三种数字,相邻的节点的和必须是奇数,问有多少中方法。
题意: 给你一个图,每个节点可以赋值1,2,3三种数字,相邻的节点的和必须是奇数,问有多少中方法. 分析: 很容易就可以发现如果这个图中是有奇数的环的话,那这是肯定不行的 ,否则这个环的贡献是为2^s ...
- 高精度的N进制转换模板(转K神)
/* 高精度进制转换 把oldBase 进制的数转化为newBase 进制的数输出. 调用方法,输入str, oldBase newBase. change(); solve(); output(); ...
- vuex的小疑问记录
actions和mutations的区别是Action提交的是Mutation,不能够直接修改state中的状态,而Mutations是可以直接修改state中状态的:Action是支持异步操作的,而 ...
- git 如何删除远程提交方法总结
今天不小心把代码提到主分支了,虽然改动只有一点点,但感觉asdasdasdsadd(要被骂死) 怎么样才能删除掉远程的分支呢. 假设我们有提交 commit commit commit 手残把3提交错 ...