SpringBoot系列(18):SpringBoot整合MongoDB實戰(zhàn)一之新增修改與簡單查詢

作者: 修羅debug
版權聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處鏈接和本聲明。


摘要:MongoDB,也稱之為文檔型數據庫,是目前市面上相當流行的其中一種NoSQL數據庫,也是眾多NoSQL數據庫中最接近于“關系型數據庫”的非關系型數據庫,可以實現對象實體信息以“Document文檔”的形式進行存儲。我們花2篇文章分享介紹如何基于Spring Boot2.0搭建的項目整合MongoDB中間件,實現如何對業(yè)務模塊進行CRUD與分頁查詢。

內容:文檔型數據庫MongoDB是眾多NoSQL數據庫的一種,在如今的企業(yè)級應用系統、特別是大數據的應用系統中,其普及程度也是越來越高,如下圖所示,為DB-Engine在2019年10月份發(fā)布的數據庫的使用排名(只截取部分圖,其余詳細的大家可以自己去看看):


你會發(fā)現,排在前四/五的幾位是目前數據庫領域中長期霸占著“老大哥地位”的幾種“關系型數據庫”,即Oracle、MySQL、SQL Server和PostgreSQL,而緊隨其后的則是MongoDB,連Redis都還得跟它隔著2個檔次!在這里,順便給大家交代一下MongoDB的中文技術社區(qū):http://www.mongoing.com/ 及其中文文檔:http://www.mongoing.com/docs/

事實上,MongoDB在實際的項目開發(fā)中也逐漸得到了普及,特別是在一些需要實現海量數據存儲、查詢功能以及高并發(fā)、高可用的業(yè)務場景,MongoDB更是能發(fā)揮其穩(wěn)定、高效和可靠的性能(據說單節(jié)點MongoDB可以輕松存取億級容量的數據)!

因此,我們覺得是時候擼一波MongoDB在企業(yè)級應用項目中的代碼實戰(zhàn)了。工欲善其事,必先利其器,在開擼之前,我們需要在本地或者云服務器安裝好MongoDB服務,當然啦,Debug建議最好也同時在本地安裝一個“MongoDB可視化管理工具”,在這里我推薦Robo 3T,如下圖所示:


其安裝過程,在這里Debug就不貼出來了,大伙兒自己要學會多動手,所謂“自己動手、豐衣足食”便是這個道理!

值得一提的是,文檔型數據庫MongoDB,顧名思義,其底層存儲的一條數據便是一個“Document”,即文檔,多個文檔便組成了一個“Collection”,即集合,多個集合便組成了一個“DataBase”,即數據庫。這樣子聽起來,你會發(fā)現它跟“關系型數據庫”在一些專業(yè)詞匯上有些雷同之處,下面為Debug親自制作的一張MongoDB與關系型數據庫在一些專有詞匯上的聯系圖(切記:只是含義上的聯系哈!在底層或者業(yè)務層面是一丁點關系都沒有的),這張圖可以方便各位小伙伴理解、記憶MongoDB的相關專業(yè)詞匯,在后續(xù)代碼實戰(zhàn)中才不會懵逼!


最后一點,需要重點提及的是,MongoDB底層最終存儲的一條一條的Document、一條一條的文檔記錄,而這些文檔記錄的數據結構是“Json格式”的,如下圖所示:


好了,說了這么多,是時候進入實戰(zhàn)環(huán)節(jié)了,下面我們就以之前搭建的Spring Boot2.0企業(yè)級的項目為奠基,整合MongoDB中間件,然后以“用戶模塊User”為業(yè)務模塊案例,初步體驗Spring Boot2.0整合MongoDB 實現基本的新增、修改與簡單的查詢。

(1)首先,自然是需要貼出用戶模塊User對應的數據庫表user啦,其DDL定義如下所示:

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '名字',
`code` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '工號',
`email` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '郵箱',
`is_active` int(11) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶信息表';

緊接著,為了能在我們的企業(yè)級應用中使用MongoDB服務,我們需要加入MongoDB中間件相關的服務依賴以及服務配置,在pom.xml中加入依賴,如下所示:  

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

在配置文件application.properties中加入MongoDB服務的鏈接配置,如下所示:  

#mongodb

#方式一
#spring.data.mongodb.uri=mongodb://localhost:27017/SpringBootMongoDB
#spring.data.mongodb.uri=mongodb://root:root@127.0.0.1:27017/SpringBootMongoDB

#方式二
spring.data.mongodb.database=SpringBootMongoDB
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
#spring.data.mongodb.username=
#spring.data.mongodb.password=

在上面,Debug提供了兩種方式可供大家自行選擇配置。而我們會在后續(xù)接下來的代碼實戰(zhàn)中使用MongoDB服務提供給開發(fā)者使用的便捷利器:MongoTemplate,這個模板組件便會自動讀取配置文件application.properties中的相關信息,從而建立到MongoDB服務中間件的鏈接。

(2)緊接著,我們創(chuàng)建一個MongoUserRepository服務類,在其中編寫實現“新增、批量新增、更新、簡單列表查詢和主鍵查詢”的邏輯,如下所示:

/**
* @Author:debug (SteadyJack)
* @Link: weixin-> debug0868 qq-> 1948831260
* @Date: 2019/11/13 11:14
**/
@Component
public class MongoUserRepository{
private static final Logger log= LoggerFactory.getLogger(MongoUserRepository.class);

@Autowired
private MongoTemplate mongoTemplate;

@Autowired
private UserMapper userMapper;

//TODO:新增:先插入數據,再插入MongoDB(也可以不插入數據庫,而直接插入MongoDB)
@Transactional(rollbackFor = Exception.class)
public void save(final MongoUser user) throws Exception{
User entity=new User();
BeanUtils.copyProperties(user,entity, "id");
userMapper.insertSelective(entity);

user.setId(entity.getId());
mongoTemplate.save(user);
}

//TODO:批量新增
public void saveAll(final List<MongoUser> list) throws Exception{
if (list!=null && !list.isEmpty()){
list.forEach(user -> {
log.info("-------mongoDB批量新增---------");

User entity=new User();
BeanUtils.copyProperties(user,entity, "id");
userMapper.insertSelective(entity);

user.setId(entity.getId());
});
mongoTemplate.insertAll(list);
}
}

//TODO:查詢-列表
public List<MongoUser> queryAll() throws Exception{
return mongoTemplate.findAll(MongoUser.class);
}

//TODO:查詢-主鍵查詢
public MongoUser queryById(final Integer id) throws Exception{
return mongoTemplate.findById(id,MongoUser.class);
}

//TODO:查詢-帶條件查詢
public List<MongoUser> queryByName(final String name) throws Exception{
Criteria criteria=Criteria.where("name").is(name);
return mongoTemplate.find(Query.query(criteria),MongoUser.class);
}

//TODO:更新
@Transactional(rollbackFor = Exception.class)
public void update(final MongoUser user) throws Exception{
User entity=new User();
BeanUtils.copyProperties(user,entity);
userMapper.updateByPrimaryKeySelective(entity);

Query query=Query.query(Criteria.where("id").is(user.getId()));
Update update=Update.update("name",user.getName()).set("code",user.getCode()).set("email",user.getEmail());
mongoTemplate.updateFirst(query,update,MongoUser.class);
}
}

上述相應方法的代碼邏輯其實也不是很難理解,擼過Spring Data JPA的小伙伴估計對于其中的Query、Criteria啥的會感覺相當親切!接下來,我們需要單獨寫一寫每個方法的測試案例!

(1)首先,我們先來插入一個用戶信息,即一條文檔記錄吧,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MainApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MongoTest2 {
private static final Logger log= LoggerFactory.getLogger(MongoTest2.class);

@Autowired
private MongoUserRepository mongoUserRepository;

@Test
public void method1() throws Exception{
log.info("---單元測試1---");
List<MongoUser> list=mongoUserRepository.queryAll();
log.info("---查詢所有:{}---",list);

MongoUser mongoUser=new MongoUser(null,"曹操","20010","caocao@qq.com",1);
mongoUserRepository.save(mongoUser);
log.info("-----插入成功-----");

list=mongoUserRepository.queryAll();
log.info("---查詢所有:{}---",list);
}
}

運行該Java單元測試案例,可以得到如下圖的運行結果:


(2)除此之外,我們可以對其進行“批量新增”、“列表查詢與主鍵查詢”和“更新”操作,其剩余的Java單元測試案例代碼如下所示:

    @Test
public void method2() throws Exception{
log.info("---單元測試2---");
List<MongoUser> list= Lists.newLinkedList();
list.add(new MongoUser(null,"宋江","40021","40021@126.com",1));
list.add(new MongoUser(null,"盧俊義","40022","40022@126.com",1));
list.add(new MongoUser(null,"吳用","40023","40023@126.com",1));
list.add(new MongoUser(null,"魯智深","40024","40024@126.com",1));
list.add(new MongoUser(null,"武松","40025","40025@126.com",1));

list.add(new MongoUser(null,"曹操","50001","50001@qq.com",1));
list.add(new MongoUser(null,"劉備","50002","50002@qq.com",1));
list.add(new MongoUser(null,"孫權","50003","50003@qq.com",1));
list.add(new MongoUser(null,"關羽","50004","50004@qq.com",1));
list.add(new MongoUser(null,"趙云","50005","50005@qq.com",1));

mongoUserRepository.saveAll(list);
log.info("-----批量插入成功-----");

list=mongoUserRepository.queryAll();
log.info("---查詢所有:{}---",list);
}

@Test
public void method3() throws Exception{
log.info("---單元測試3---");

final Integer id=343686;
MongoUser entity=mongoUserRepository.queryById(id);
log.info("---根據主鍵id查詢={},結果={}---",id,entity);

final String name="張飛";
List<MongoUser> list=mongoUserRepository.queryByName(name);
log.info("---根據姓名查詢,name={},結果={}---",name,list);
}

@Test
public void method4() throws Exception{
log.info("---單元測試4---");

MongoUser entity=new MongoUser(343686,"李四","30023","lisi@sina.com",1);
mongoUserRepository.update(entity);

entity=mongoUserRepository.queryById(343686);
log.info("---根據主鍵id查詢,結果={}---",entity);
}

運行相應的測試方法,并觀察控制臺所打印出來的結果,如果沒啥問題,即可打開Navicat以及Robo 3T查看相應的數據的狀況,最終你會發(fā)現也是沒啥問題!

對于MongoDB的初步體驗至此我們結束了,但是MongoDB的強大之處卻不僅僅局限于此,在文章的開始我們就給大家交代過了,MongoDB底層采用的是“列式存儲”、Json格式數據結構來存儲數據的,特別適用于大數據量、海量數據的存儲以及查詢。故而在下一篇章,我們將往MongoDB塞入40多萬(當然啦,也可以是百萬、千萬甚至是億級別)的數據,然后再給大家分享一下分頁查詢和刪除的功能。

好了,本篇文章我們就介紹到這里了,其他相關的技術,感興趣的小伙伴可以關注底部Debug的技術公眾號,或者加Debug的微信,拉你進“微信版”的真正技術交流群!一起學習、共同成長!

補充:

1、本文涉及到的相關的源代碼可以到此地址,check出來進行查看學習:

https://gitee.com/steadyjack/SpringBootTechnology

2、最近Debug發(fā)布了幾門重量級的課程,感興趣的小伙伴可以前往觀看學習:
(1) 緩存中間件Redis技術入門與應用場景實戰(zhàn)(SpringBoot2.x + 搶紅包系統設計與實戰(zhàn)) 
https://www.fightjava.com/web/index/course/detail/12

(2)  企業(yè)權限管理平臺(SpringBoot2.0+Shiro+Vue+Mybatis)
https://www.fightjava.com/web/index/course/detail/8

3、關注一下Debug的技術微信公眾號,最新的技術文章、課程以及技術專欄將會第一時間在公眾號發(fā)布哦!