SpringBoot整合MongoDB(實現一個簡單緩存)


前言

SpringBoot是常用開發框架,而MongoDB也是最近越來越火的非關系型數據庫,這里使用SpringBoot+MongoDB實現一個小案例,當然MongoDB實際做緩存的可能不多,但是這里僅僅為了一個小demo簡單的學習使用,入門上手為目的,更多的復雜查詢還需關注MongoDB官網。

如果本篇對你有幫助,還請點贊支持一下!微信搜索 bigsai 回復bigsai獲取珍藏學習pdf一份!

如果對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資源一份!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM