SpringBoot整合MongoDB(实现一个简单缓存)
前言
SpringBoot是常用开发框架,而MongoDB也是最近越来越火的非关系型数据库,这里使用SpringBoot+MongoDB实现一个小案例,当然MongoDB实际做缓存的可能不多,但是这里仅仅为了一个小demo简单的学习使用,入门上手为目的,更多的复杂查询还需关注MongoDB官网。
如果本篇对你有帮助,还请点赞支持一下!原创作者:
bigsai
如果对MongoDB不太了解,还请先看上篇MongoDB从立地到成佛。
创建MongoDB数据库和项目
创建MongoDB数据库
打开Studio 3T数据库管理工具,连接本地MongoDB数据库之后,创建名为test的数据库,在test数据库中创建名为news得集合:
创建项目
首先,打开IDEA创建项目,选择创建Springboot项目:
然后在选择Gruop和Aritifact时候分别填写com和mongodemo,Java Version选择8版本。
在勾选模块时候,这里勾选Spring web、MongoDB依赖模块,选择合适位置创建项目,项目就可以成功创建:
预备工作
创建完项目,我们需要做一些预备工作用来完成缓存。我们首先要在项目中的application.properties中添加配置连接到数据库,配置规则为:spring.data.mongodb.uri=mongodb://地址:端口/数据库名
,本案例使用本地的MongoDB数据库,默认端口为27017,而使用的MongoDB具体数据库名称为test,那么就可以按照以下进行配置:
spring.data.mongodb.uri=mongodb://localhost:27017/test
这样在项目中就可以连接到本地的MongoDB的test数据库并访问。
其次在项目中com.mongodb目录下分别创建controller,service,pojo文件夹,在controller文件夹下创建newsController.java
类,为负责url和逻辑的控制器:
package com.mongodemo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class newsController {
private static Logger logger= LoggerFactory.getLogger(newsController.class);
}
其中:
- @RestController就声明该类为一个控制器,并且返回JSON字符串给前端。
- 而Logger对象用于打印日志。在web项目中我们更倾向于使用log打印日志而不在控制台直接输出。
controller创建完毕在service 文件夹下创建NewsService.java
类,里面先编写以下内容:
package com.mongodemo.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
@Service
public class NewsService {
private static Logger logger= LoggerFactory.getLogger(NewsService.class);
@Autowired
MongoTemplate mongoTemplate;
}
其中:
- @Service 表示该类为一个service(事务处理),可以被注入到其他对象(Spring帮你管理)。
- @Autowired表示要注入对象的意思。而MongoTemplate 就是已经封装好在Spring中操作MongoDB的对象。
service创建完成,我们需要在pojo中创建news类,代表新闻实体内容。
import java.util.Date;
public class news {
private String title;
private Date date;
private String brief;
private String content;
private String author;
@Override
public String toString() {
return "news{" +
"title='" + title + '\'' +
", date=" + date +
", brief='" + brief + '\'' +
", content='" + content + '\'' +
", author='" + author + '\'' +
'}';
}
public news(String title, Date date, String brief, String content, String author) {
this.title = title;
this.date = date;
this.brief = brief;
this.content = content;
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getBrief() {
return brief;
}
public void setBrief(String brief) {
this.brief = brief;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
其中各个字段分别表示为:
名称 | 含义 |
---|---|
title | 标题 |
date | 日期 |
brief | 概要 |
content | 内容 |
author | 作者 |
缓存查询
下面开始实战MongoDB实现一个新闻得缓存功能,实现缓存之前,要清楚缓存的核心作用:提升web程序的查询速度,将热点数据放到非关系数据库中。本案例对接口进行缓存,不过真正的缓存实例需要考虑很多问题比如时效性,缓存那些数据等。在这里主要为了讲解MongoDB的一个实例。
在查询时候,缓存和数据库之间通常是这么配合的:
为了降低整个项目的复杂度,这里用手动生成的数据对象代替成数据库中查询的数据,我们在NewsService中编写getNewsByTitle(String title)函数,其功能是根据标题返回缓存或数据库中该条news数据,如果MongoDB中存在则直接返回该对象,否则先从数据库查询(这里直接生成),然后存到MongoDB中再返回。具体代码为:
public news getNewsByTitle(String title)
{
//查询数据先从MongoDB中查询
Query query = new Query(Criteria.where("title").is(title));
news news=mongoTemplate.findOne(query, news.class);
if(news==null)//缓存中没该条记录
{
logger.info("从数据库查询数据");
//假设news1从数据库中查询
news news1=new news(title,new Date(),"","","bigsai");
news1.setBrief("有了博学谷,妈妈再也不用担心我的java学习!");
news1.setContent("博学谷优质学习资料为java学习提供更好环境,越来越多开发者学习使用");
mongoTemplate.insert(news1,"news");
logger.info("数据插入到MongoDB成功");
news=news1;
}
else {
logger.info("数据从缓存访问成功");
}
return news;
}
上面的代码中:
- 我们核心使用mongoTemplate对象来实现查询一条记录,查询语句为:mongoTemplate.findOne(query, news.class),第一个参数为查询的条件,第二个参数为查询结果转成Java对象的类型,它帮你自动处理。
- 通过Query对象来辅助我们实现条件查询,这里的意思就是查询条件为:MongoDB中title字段为传进来title字符串的该条记录。
- 而插入的语法为 mongoTemplate.insert(news1,"news"),第一个参数为插入的文档记录,第二个参数为连接呃MongoDB对应数据库下的集合(Collections)。
在newsController中,我们编写一个名称为getnews的接口,用来给用户返回该标题新闻(news类)的一条数据的JSON文件,具体代码为:
@Autowired
NewsService newsService;
@GetMapping("getnews/{title}")
public news getnews(@PathVariable String title)
{
news news=newsService.getNewsByTitle(title);
return news;
}
上面代码中:
- @Autowired(required = false)用来注入对象,下面的NewsService userService就是被注入的对象,注入之后不需要手动创建对象可以直接使用(Spring帮你管理)
- @GetMapping("getnews/{title}") 意为声明一个get请求方式的接口,
我们启动程序,浏览器输入localhost:8080/getnews/好好学java
页面会有返回的结果,返回的一个news对象序列化成JSON的字符串的文本。
同时,你查看IDEA的日志,由于第一次查询,MongoDB中没有对应数据你会发现会先从数据库中查询然后存储到MongoDB中:
查看MongoDB的news集合发现记录被成功插入了,多刷新页面localhost:8080/getnews/好好学java
你会发现数据会直接从MongoDB中返回:
缓存更新、删除
缓存中的数据和存储的关系数据库的数据是一致的,当我们只有查询操作的时候,可以一直保持数据的一致性,但是我们如果对数据有更新、删除的操作,就需要对关系数据库和MongoDB中的数据同时进行更新或删除的操作,让数据再次达到一致性的效果。
缓存更新
虽然大部分情况我们对热点新闻数据可能很少更新,但是也有时候新闻中有部分内容需要更改的需要我们完成,比如比分错字或者不妥的言论。
我们在NewsService中编写updateNewsContentByTitle((String title,String content)函数,其作用为更新数据库(这里没有具体实现)和MongoDB缓存中的数据:
public boolean updateNewsContentByTitle(String title,String content)
{
try {
Query query = new Query(Criteria.where("title").is(title));
Update update = new Update();
update.set("content", content);//更新内容
update.set("date",new Date());//更新时间
// 假设在这里数据库中更新过这里跳过
// updateFirst 更新查询返回结果集的第一条
//upsert 更新如果不存在就插入
mongoTemplate.upsert(query, update, news.class);
}
catch (Exception e)
{
return false;
}
return true;
}
其中:
- Query对象来辅助我们实现条件查询待更新数据,这里的意思就是查询条件同样为:MongoDB中title字段为传进来title字符串的该条记录。
- Update对象用来记录更新的字段和数据,这里更新传进来的content内容和date日期。
- mongoTemplate.upsert(query, update, news.class)用来实现更新,如果MongoDB中不存在该数据那么就插入到MongoDB中。
编写完service,在newsController中编写一个名为updatenews的接口,用来更新数据库数据和缓存在MongoDB的数据:
@GetMapping("updatenews")
public String updatenews(String title,String content)
{
boolean bool=newsService.updateNewsContentByTitle(title,content);
if(bool)
return "更新成功";
else
return "更新失败";
}
启动程序访问localhost:8080/updatenews?title=好好学java&content=学好java走遍全天下
,你会发现数据更新成功:
缓存删除
除了更新的时候需要保证数据一致性,删除的时候也需要保证数据一致性,如果在删除关系数据库的数据而不删除MongoDB缓存,那么下次查询该条数据MongoDB中存在而关系数据库中不存在,这样就造成了数据不一致,所以在删除数据的时候我们需要在MongoDB中的数据也删除。
在NewsService中编写deleteNewsByTitle(String title)函数,用来根据标题title删除MongoDB中的记录:
public boolean deleteNewsByTitle(String title)
{
try {
Query query = new Query(Criteria.where("title").is(title));
mongoTemplate.remove(query,news.class);
}
catch (Exception e)
{
return false;
}
return true;
}
mongoTemplate.remove(query,news.class);意味从MongoDB中删除满足查询条件的记录。其中query为查询条件,news.class为删除对象在Java中的类。
在newsController中编写deletenews接口,用来处理删除的请求:
@GetMapping("deletenews/{title}")
public String deletenews(@PathVariable String title)
{
try {
newsService.deleteNewsByTitle("好好学java");
return "删除成功";
}
catch (Exception e)
{
return "删除失败";
}
}
启动程序,访问http://localhost:8080/deletenews/好好学java
,会发现缓存在MongoDB中的记录被成功删除,这样就保证MongoDB中不会出现关系数据库中不存在的脏数据,达到数据一致性!
本篇到这里就结束了,如果帮助还请不要吝啬你的小赞、收藏一份如有更多期待还请关注公众号bigsai
,回复bigsai获取珍藏pdf资源一份!
SpringBoot整合MongoDB(实现一个简单缓存)的更多相关文章
- java操作mongodb & springboot整合mongodb
简单的研究原生API操作MongoDB以及封装的工具类操作,最后也会研究整合spring之后作为dao层的完整的操作. 1.原生的API操作 pom.xml <!-- https://mvnre ...
- SpringBoot整合mongoDB
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 这一片文章介绍一个springboot整合mongodb,如果你了解整合mysql之类的 ...
- 利用SpringBoot+Logback手写一个简单的链路追踪
目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...
- Springboot整合MongoDB的Docker开发,其它应用也类似
1 前言 Docker是容器开发的事实标准,而Springboot是Java微服务常用框架,二者必然是会走到一起的.本文将讲解如何开发Springboot项目,把它做成Docker镜像,并运行起来. ...
- Springboot 整合 MongoDB
Springboot 整合 MongoDB 这节我们将整合 Spring Boot 与 Mongo DB 实现增删改查的功能,并且实现序列递增. Mongo DB 的基本介绍和增删改查的用法可以参考我 ...
- SpringBoot 整合 MongoDB 实战介绍
一.介绍 在前面的文章中,我们详细的介绍了 MongoDB 的配置和使用,如果你对 MongoDB 还不是很了解,也没关系,在 MongoDB 中有三个比较重要的名词:数据库.集合.文档! 数据库(D ...
- SpringBoot 整合mongoDB并自定义连接池
SpringBoot 整合mongoDB并自定义连接池 得力于SpringBoot的特性,整合mongoDB是很容易的,我们整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它 ...
- 8、SpringBoot整合之SpringBoot整合MongoDB
SpringBoot整合MongoDB 一.创建项目,选择依赖 仅选择Spring Web.Spring Data MongoDB即可 二.引入相关依赖(非必要) 这里只是为了实体类的创建方便而引入l ...
- MongoDB系列:三、springboot整合mongoDB的简单demo
在上篇 MongoDB常用操作练习 中,我们在命令提示符窗口使用简单的mongdb的方法操作数据库,实现增删改查及其他的功能.在本篇中,我们将mongodb与spring boot进行整合,也就是在j ...
随机推荐
- kali安装open-vm-tools实现虚拟机交互
普通的VMware tools 弱爆了 安装具有复制粘贴功能的open-vm-tools.servic: 切记:如果之前已经安装了VMware tools,一定要删除:vmware-uninstall ...
- latex:公式中的文字
公式环境中的说明文字应置于\mbox命令中.如果已经调用了数学工具宏包或者公式宏包,可改为选用一下3条功能更强的文本命令将简短文字插入公式中. \intertext{文本} 由amsmath宏包提供, ...
- SPSSAU数据分析思维培养系列1:数据思维篇
今天,SPSSAU给大家带来[数据分析思维培养]系列课程.主要针对第一次接触数据分析,完全不懂分析的小白用户,或者懂一些简单方法但苦于没有分析思路,不知道如何规范化分析. 本文章为SPSSAU数据分析 ...
- JavaScript中pipe实战
JavaScript中pipe原理 代码示例 const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x); 原理 一行代码 ...
- 3点带你快速学会Selenium工具的使用
(一)Selenium IDE Firefox的一个插件,有助于我们理解测试框架.在附加组件里搜索下载,一般搜的结果里前几个都不是,得点那个查看更多才行,找到这个: 安装以后浏览器工具栏会有: 安装好 ...
- tomcat服务器java.lang.OutOfMemoryError: PermGen space
一挂就报内存溢出 下面是TOMCAT日志 JAVA程序是没有报错, Nov 24, 2009 4:07:02 PM org.apache.catalina.core.ApplicationDispat ...
- 数据库系统第六章【关系数据理论】(B站视频)
目录 数据库系统第六章[关系数据理论](B站视频) 一.前言 二.规范化 函数依赖 三种分类 如何确定函数依赖? 平凡函数依赖vs非平凡函数依赖 完全函数依赖vs部分函数依赖 传递函数依赖 码 超码 ...
- Java诞生及优势
C语言 1972年诞生 贴近硬件,速度快 指针和内存管理重点 C++ 1982年诞生 面向对象 兼容C 图形领域.游戏等 Java 基于C 没有指针和内存管理 可移植,编写一次到处运行,JVM 面向对 ...
- JavaWeb三大器(过滤器、拦截器、监听器)概念梳理
最近工作碰到了一个问题:项目A需要收集项目B中的用户活跃数信息,最后通过HttpSessionAttributeListener实现.在开发过程中,网上查找了过滤器.拦截器.监听器的帖子,这里对自己收 ...
- Template DB MySQL学习总结
Zabbix 5.0下如何应用Template DB MySQL来监控MySQL数据库呢?下面简单整理一下如何配置.应用Zabbix下自带的模板Template DB MySQL.其实非常简单. Te ...