Spring Boot 中使用 MongoDB 增刪改查

本文快速入門,MongoDB 結合SpringBoot starter-data-mongodb 進行增刪改查

1、什麼是MongoDB ?

MongoDB 是由C++語言編寫的,是一個基於分散式文件存儲的開源資料庫系統。

在高負載的情況下,添加更多的節點,可以保證伺服器性能。

MongoDB 旨在為WEB應用提供可擴展的高性能數據存儲解決方案。

MongoDB 將數據存儲為一個文檔,數據結構由鍵值(key=>value)對組成。

MongoDB 文檔類似於 JSON 對象。欄位值可以包含其他文檔,數組及文檔數組。

2、MongoDB 優缺點

優點

  • 文檔結構的存儲方式,能夠更便捷的獲取數據
  • 內置GridFS,支持大容量的存儲
  • 海量數據下,性能優越
  • 動態查詢
  • 全索引支持,擴展到內部對象和內嵌數組
  • 查詢記錄分析
  • 快速,就地更新
  • 高效存儲二進位大對象 (比如照片和視頻)
  • 複製(複製集)和支持自動故障恢復
  • 內置 Auto- Sharding 自動分片支持雲級擴展性,分片簡單
  • MapReduce 支持複雜聚合
  • 商業支持,培訓和諮詢

缺點

  • 不支持事務操作
  • MongoDB 佔用空間過大 (不過這個確定對於目前快速下跌的硬碟價格來說,也不算什麼缺點了)
  • MongoDB沒有如MySQL那樣成熟的維護工具
  • 無法進行關聯表查詢,不適用於關係多的數據
  • 複雜聚合操作通過mapreduce創建,速度慢
  • 模式自由,自由靈活的文件存儲格式帶來的數據錯
  • MongoDB 在你刪除記錄後不會在文件系統回收空間。除非你刪掉資料庫。但是空間沒有被浪費

3、優缺點詳細解釋

1.內置GridFS,支持大容量的存儲:

GridFS是一個出色的分散式文件系統,可以支持海量的數據存儲。 內置了GridFS了MongoDB,能夠滿足對大數據集的快速範圍查詢。

2.內置 Auto- Sharding 自動分片支持雲級擴展性,分片簡單

提供基於Range的Auto Sharding機制:

一個collection可按照記錄的範圍,分成若干個段,切分到不同的Shard上。

Shards可以和複製結合,配合Replica sets能夠實現Sharding+fail-over,不同的Shard之間可以負載均衡。

查詢是對客戶端是透明的。客戶端執行查詢,統計,MapReduce等操作,這些會被MongoDB自動路由到後端的數據節點。

這讓我們關注於自己的業務,適當的 時候可以無痛的升級。MongoDB的Sharding設計能力最大可支持約20 petabytes,足以支撐一般應用。

這可以保證MongoDB運行在便宜的PC伺服器集群上。PC集群擴充起來非常方便並且成本很低,避免了「sharding」操作的複雜性和成本。

3.海量數據下,性能優越:

在使用場合下,千萬級別的文檔對象,近10G的數據,對有索引的ID的查詢不會比mysql慢,而對非索引欄位的查詢,則是全面勝出。 mysql實際無法勝任大數據量下任意欄位的查詢,而mongodb的查詢性能實在讓我驚訝。寫入性能同樣很令人滿意,同樣寫入百萬級別的數 據,mongodb比我以前試用過的couchdb要快得多,基本10分鐘以下可以解決。補上一句,觀察過程中mongodb都遠算不上是CPU殺手。

4.全索引支持,擴展到內部對象和內嵌數組

索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文件並選取那些符合查詢條件的記錄。

這種掃描全集合的查詢效率是非常低的,特別在處理大量的數據時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的性能是非常致命的。

索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中,索引是對資料庫表中一列或多列的值進行排序的一種結構。

5.MapReduce 支持複雜聚合

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點類似sql語句中的 count(*)。

與關係型資料庫相比,MongoDB的缺點:

mongodb不支持事務操作:

所以事務要求嚴格的系統(如果銀行系統)肯定不能用它。

mongodb不支持事務操作:

所以事務要求嚴格的系統(如果銀行系統)肯定不能用它。

mongodb佔用空間過大:

關於其原因,在官方的FAQ中,提到有如下幾個方面:

1、空間的預分配:為避免形成過多的硬碟碎片,mongodb每次空間不足時都會申請生成一大塊的硬碟空間,而且申請的量從64M、128M、256M那 樣的指數遞增,直到2G為單個文件的最大體積。隨著數據量的增加,你可以在其數據目錄里看到這些整塊生成容量不斷遞增的文件。

2、欄位名所佔用的空間:為了保持每個記錄內的結構信息用於查詢,mongodb需要把每個欄位的key-value都以BSON的形式存儲,如果 value域相對於key域並不大,比如存放數值型的數據,則數據的overhead是最大的。一種減少空間佔用的方法是把欄位名盡量取短一些,這樣佔用 空間就小了,但這就要求在易讀性與空間佔用上作為權衡了。

3、刪除記錄不釋放空間:這很容易理解,為避免記錄刪除後的數據的大規模挪動,原記錄空間不刪除,只標記「已刪除」即可,以後還可以重複利用。

4、可以定期運行db.repairDatabase()來整理記錄,但這個過程會比較緩慢

MongoDB沒有如MySQL那樣成熟的維護工具,這對於開發和IT運營都是個值得注意的地方。

4、環境需要

64位操作系統,建議使用Linux / Unix /

  • CentOs 7.3
  • MongoDB 3.6.2

5、環境安裝

請參考我的另一篇文章

搭建 MongoDB分片(sharding) / 分區 / 集群環境

http://www.ymq.io/2018/01/30/MongoDB-3

6、新加項目

新建一個 maven 項目,這裡就不詳細操作了,大家都會的

不過也可以下載我的示例源碼,下載地址如下

GitHub:github.com/souyunku/spr

碼云:gitee.com/souyunku/spri

MongoDB是一個開源NoSQL文檔資料庫,它使用類似JSON的模式而不是傳統的基於表格的關係數據。Spring Boot為MongoDB提供了一些便利,包括 spring-boot-starter-data-mongodb 「Starter」。

7、添加依賴

在POM 中添加如下依賴

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>

8、配置文件

在配置文件 application.properties 添加如下配置

spring.application.name=spring-boot-mongodb# mongodbspring.data.mongodb.uri=mongodb://192.168.252.121:20000,192.168.252.122:20000,192.168.252.12:20000/demo

多個IP集群的配置:

spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test

9、DemoEntity

spring-data-mongodb中的實體映射是通過MongoMappingConverter這個類實現的。它可以通過注釋把java類轉換為mongodb的文檔。

它有以下幾種注釋:

@Id - 文檔的唯一標識,在mongodb中為ObjectId,它是唯一的,通過時間戳+機器標識+進程ID+自增計數器(確保同一秒內產生的Id不會衝突)構成。

@Document - 把一個java類聲明為mongodb的文檔,可以通過collection參數指定這個類對應的文檔。@Document(collection="mongodb") mongodb對應表

@DBRef - 聲明類似於關係資料庫的關聯關係。ps:暫不支持級聯的保存功能,當你在本實例中修改了DERef對象裡面的值時,單獨保存本實例並不能保存DERef引用的對象,它要另外保存,如下面例子的Person和Account。

@Indexed - 聲明該欄位需要索引,建索引可以大大的提高查詢效率。

@CompoundIndex - 複合索引的聲明,建複合索引可以有效地提高多欄位的查詢效率。

@GeoSpatialIndexed - 聲明該欄位為地理信息的索引。

@Transient - 映射忽略的欄位,該欄位不會保存到mongodb。

@PersistenceConstructor - 聲明構造函數,作用是把從資料庫取出的數據實例化為對象。該構造函數傳入的值為從DBObject中取出的數據

package io.ymq.example.mongodb;@Document(collection = "demo_collection")public class DemoEntity implements Serializable { @Id private Long id; private String title; private String description; private String by; private String url; 省略 getter setter}

10、Demo DAO 介面

提供增刪改查 MongoDB 介面

package io.ymq.example.mongodb;public interface DemoDao { void saveDemo(DemoEntity demoEntity); void removeDemo(Long id); void updateDemo(DemoEntity demoEntity); DemoEntity findDemoById(Long id);}

11、Demo DAO 實現

提供增刪改查 MongoDB 介面實現

Spring Data Mongo提供了一個 MongoTemplate類似於Spring的設計的類JdbcTemplate。和JdbcTemplateSpring Boot一樣,自動配置一個bean來簡單地注入:

package io.ymq.example.mongodb;/** * 描述: Demo DAO 實現 * * @author yanpenglei * @create 2018-02-03 16:57 **/@Componentpublic class DemoDaoImpl implements DemoDao { @Resource private MongoTemplate mongoTemplate; @Override public void saveDemo(DemoEntity demoEntity) { mongoTemplate.save(demoEntity); } @Override public void removeDemo(Long id) { mongoTemplate.remove(id); } @Override public void updateDemo(DemoEntity demoEntity) { Query query = new Query(Criteria.where("id").is(demoEntity.getId())); Update update = new Update(); update.set("title", demoEntity.getTitle()); update.set("description", demoEntity.getDescription()); update.set("by", demoEntity.getBy()); update.set("url", demoEntity.getUrl()); mongoTemplate.updateFirst(query, update, DemoEntity.class); } @Override public DemoEntity findDemoById(Long id) { Query query = new Query(Criteria.where("id").is(id)); DemoEntity demoEntity = mongoTemplate.findOne(query, DemoEntity.class); return demoEntity; }}

12、啟動服務

運行啟動類

package io.ymq.example.mongodb;@SpringBootApplicationpublic class SpringBootMongodbApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMongodbApplication.class, args); }}

13、單元測試

單元測試,提供mongodbdemo 庫的 demo_collection 集合的增刪改查

package io.ymq.example.mongodb;@RunWith(SpringRunner.class)@SpringBootTest(classes = SpringBootMongodbApplication.class)public class SpringBootMongodbApplicationTests { @Autowired private DemoDao demoDao; @Test public void saveDemoTest() { DemoEntity demoEntity = new DemoEntity(); demoEntity.setId(1L); demoEntity.setTitle("Spring Boot 中使用 MongoDB"); demoEntity.setDescription("關注公眾號,搜雲庫,專註於開發技術的研究與知識分享"); demoEntity.setBy("souyunku"); demoEntity.setUrl("http://www.souyunku.com"); demoDao.saveDemo(demoEntity); demoEntity = new DemoEntity(); demoEntity.setId(2L); demoEntity.setTitle("Spring Boot 中使用 MongoDB"); demoEntity.setDescription("關注公眾號,搜雲庫,專註於開發技術的研究與知識分享"); demoEntity.setBy("souyunku"); demoEntity.setUrl("http://www.souyunku.com"); demoDao.saveDemo(demoEntity); } @Test public void removeDemoTest() { demoDao.removeDemo(2L); } @Test public void updateDemoTest() { DemoEntity demoEntity = new DemoEntity(); demoEntity.setId(1L); demoEntity.setTitle("Spring Boot 中使用 MongoDB 更新數據"); demoEntity.setDescription("關注公眾號,搜雲庫,專註於開發技術的研究與知識分享"); demoEntity.setBy("souyunku"); demoEntity.setUrl("http://www.souyunku.com"); demoDao.updateDemo(demoEntity); } @Test public void findDemoByIdTest() { DemoEntity demoEntity = demoDao.findDemoById(1L); System.out.println(JSONObject.toJSONString(demoEntity)); }}

擴展閱讀

手把手教你 MongoDB 的安裝與詳細使用(一)

ymq.io/2018/01/26/Mongo

手把手教你 MongoDB 的安裝與詳細使用(二)

ymq.io/2018/01/29/Mongo

源碼下載

GitHub:github.com/souyunku/spr

碼云:gitee.com/souyunku/spri

福利

Spring Boot 學習教程 會不定時更新技術, 歡迎 Star 和 Fork。

github.com/souyunku/spr

github.com/souyunku/spr

參考:docs.spring.io/spring-b

Contact

  • 作者:鵬磊
  • 出處:ymq.io/2018/02/05/sprin
  • Email:admin@souyunku.com
  • 版權歸作者所有,轉載請註明出處
  • Wechat:關注公眾號,搜雲庫,專註於開發技術的研究與知識分享

weixin.qq.com/r/0UwmPsn (二維碼自動識別)

推薦閱讀:

Spring boot與Spring cloud 是什麼關係?
關於Spring MVC的教程和例子?
spring-jdbc 目前還是一個主流的廣泛使用的持久化框架嗎?
springboot怎麼學?

TAG:SpringBoot | MongoDB |