SpringBoot系列(18):SpringBoot整合MongoDB實(shí)戰(zhàn)一之新增修改與簡(jiǎn)單查詢
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
摘要:MongoDB,也稱之為文檔型數(shù)據(jù)庫(kù),是目前市面上相當(dāng)流行的其中一種NoSQL數(shù)據(jù)庫(kù),也是眾多NoSQL數(shù)據(jù)庫(kù)中最接近于“關(guān)系型數(shù)據(jù)庫(kù)”的非關(guān)系型數(shù)據(jù)庫(kù),可以實(shí)現(xiàn)對(duì)象實(shí)體信息以“Document文檔”的形式進(jìn)行存儲(chǔ)。我們花2篇文章分享介紹如何基于Spring Boot2.0搭建的項(xiàng)目整合MongoDB中間件,實(shí)現(xiàn)如何對(duì)業(yè)務(wù)模塊進(jìn)行CRUD與分頁(yè)查詢。
內(nèi)容:文檔型數(shù)據(jù)庫(kù)MongoDB是眾多NoSQL數(shù)據(jù)庫(kù)的一種,在如今的企業(yè)級(jí)應(yīng)用系統(tǒng)、特別是大數(shù)據(jù)的應(yīng)用系統(tǒng)中,其普及程度也是越來(lái)越高,如下圖所示,為DB-Engine在2019年10月份發(fā)布的數(shù)據(jù)庫(kù)的使用排名(只截取部分圖,其余詳細(xì)的大家可以自己去看看):
你會(huì)發(fā)現(xiàn),排在前四/五的幾位是目前數(shù)據(jù)庫(kù)領(lǐng)域中長(zhǎng)期霸占著“老大哥地位”的幾種“關(guān)系型數(shù)據(jù)庫(kù)”,即Oracle、MySQL、SQL Server和PostgreSQL,而緊隨其后的則是MongoDB,連Redis都還得跟它隔著2個(gè)檔次!在這里,順便給大家交代一下MongoDB的中文技術(shù)社區(qū):http://www.mongoing.com/ 及其中文文檔:http://www.mongoing.com/docs/
事實(shí)上,MongoDB在實(shí)際的項(xiàng)目開發(fā)中也逐漸得到了普及,特別是在一些需要實(shí)現(xiàn)海量數(shù)據(jù)存儲(chǔ)、查詢功能以及高并發(fā)、高可用的業(yè)務(wù)場(chǎng)景,MongoDB更是能發(fā)揮其穩(wěn)定、高效和可靠的性能(據(jù)說(shuō)單節(jié)點(diǎn)MongoDB可以輕松存取億級(jí)容量的數(shù)據(jù))!
因此,我們覺得是時(shí)候擼一波MongoDB在企業(yè)級(jí)應(yīng)用項(xiàng)目中的代碼實(shí)戰(zhàn)了。工欲善其事,必先利其器,在開擼之前,我們需要在本地或者云服務(wù)器安裝好MongoDB服務(wù),當(dāng)然啦,Debug建議最好也同時(shí)在本地安裝一個(gè)“MongoDB可視化管理工具”,在這里我推薦Robo 3T,如下圖所示:
其安裝過程,在這里Debug就不貼出來(lái)了,大伙兒自己要學(xué)會(huì)多動(dòng)手,所謂“自己動(dòng)手、豐衣足食”便是這個(gè)道理!
值得一提的是,文檔型數(shù)據(jù)庫(kù)MongoDB,顧名思義,其底層存儲(chǔ)的一條數(shù)據(jù)便是一個(gè)“Document”,即文檔,多個(gè)文檔便組成了一個(gè)“Collection”,即集合,多個(gè)集合便組成了一個(gè)“DataBase”,即數(shù)據(jù)庫(kù)。這樣子聽起來(lái),你會(huì)發(fā)現(xiàn)它跟“關(guān)系型數(shù)據(jù)庫(kù)”在一些專業(yè)詞匯上有些雷同之處,下面為Debug親自制作的一張MongoDB與關(guān)系型數(shù)據(jù)庫(kù)在一些專有詞匯上的聯(lián)系圖(切記:只是含義上的聯(lián)系哈!在底層或者業(yè)務(wù)層面是一丁點(diǎn)關(guān)系都沒有的),這張圖可以方便各位小伙伴理解、記憶MongoDB的相關(guān)專業(yè)詞匯,在后續(xù)代碼實(shí)戰(zhàn)中才不會(huì)懵逼!
最后一點(diǎn),需要重點(diǎn)提及的是,MongoDB底層最終存儲(chǔ)的一條一條的Document、一條一條的文檔記錄,而這些文檔記錄的數(shù)據(jù)結(jié)構(gòu)是“Json格式”的,如下圖所示:
好了,說(shuō)了這么多,是時(shí)候進(jìn)入實(shí)戰(zhàn)環(huán)節(jié)了,下面我們就以之前搭建的Spring Boot2.0企業(yè)級(jí)的項(xiàng)目為奠基,整合MongoDB中間件,然后以“用戶模塊User”為業(yè)務(wù)模塊案例,初步體驗(yàn)Spring Boot2.0整合MongoDB 實(shí)現(xiàn)基本的新增、修改與簡(jiǎn)單的查詢。
(1)首先,自然是需要貼出用戶模塊User對(duì)應(yīng)的數(shù)據(jù)庫(kù)表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 '工號(hào)',
`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è)級(jí)應(yīng)用中使用MongoDB服務(wù),我們需要加入MongoDB中間件相關(guān)的服務(wù)依賴以及服務(wù)配置,在pom.xml中加入依賴,如下所示:
<!--mongodb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
在配置文件application.properties中加入MongoDB服務(wù)的鏈接配置,如下所示:
#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提供了兩種方式可供大家自行選擇配置。而我們會(huì)在后續(xù)接下來(lái)的代碼實(shí)戰(zhàn)中使用MongoDB服務(wù)提供給開發(fā)者使用的便捷利器:MongoTemplate,這個(gè)模板組件便會(huì)自動(dòng)讀取配置文件application.properties中的相關(guān)信息,從而建立到MongoDB服務(wù)中間件的鏈接。
(2)緊接著,我們創(chuàng)建一個(gè)MongoUserRepository服務(wù)類,在其中編寫實(shí)現(xiàn)“新增、批量新增、更新、簡(jiǎn)單列表查詢和主鍵查詢”的邏輯,如下所示:
/**
* @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:新增:先插入數(shù)據(jù),再插入MongoDB(也可以不插入數(shù)據(jù)庫(kù),而直接插入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);
}
}
上述相應(yīng)方法的代碼邏輯其實(shí)也不是很難理解,擼過Spring Data JPA的小伙伴估計(jì)對(duì)于其中的Query、Criteria啥的會(huì)感覺相當(dāng)親切!接下來(lái),我們需要單獨(dú)寫一寫每個(gè)方法的測(cè)試案例!
(1)首先,我們先來(lái)插入一個(gè)用戶信息,即一條文檔記錄吧,如下所示:
@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("---單元測(cè)試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);
}
}
運(yùn)行該Java單元測(cè)試案例,可以得到如下圖的運(yùn)行結(jié)果:
(2)除此之外,我們可以對(duì)其進(jìn)行“批量新增”、“列表查詢與主鍵查詢”和“更新”操作,其剩余的Java單元測(cè)試案例代碼如下所示:
@Test
public void method2() throws Exception{
log.info("---單元測(cè)試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,"孫權(quán)","50003","50003@qq.com",1));
list.add(new MongoUser(null,"關(guān)羽","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("---單元測(cè)試3---");
final Integer id=343686;
MongoUser entity=mongoUserRepository.queryById(id);
log.info("---根據(jù)主鍵id查詢={},結(jié)果={}---",id,entity);
final String name="張飛";
List<MongoUser> list=mongoUserRepository.queryByName(name);
log.info("---根據(jù)姓名查詢,name={},結(jié)果={}---",name,list);
}
@Test
public void method4() throws Exception{
log.info("---單元測(cè)試4---");
MongoUser entity=new MongoUser(343686,"李四","30023","lisi@sina.com",1);
mongoUserRepository.update(entity);
entity=mongoUserRepository.queryById(343686);
log.info("---根據(jù)主鍵id查詢,結(jié)果={}---",entity);
}
運(yùn)行相應(yīng)的測(cè)試方法,并觀察控制臺(tái)所打印出來(lái)的結(jié)果,如果沒啥問題,即可打開Navicat以及Robo 3T查看相應(yīng)的數(shù)據(jù)的狀況,最終你會(huì)發(fā)現(xiàn)也是沒啥問題!
對(duì)于MongoDB的初步體驗(yàn)至此我們結(jié)束了,但是MongoDB的強(qiáng)大之處卻不僅僅局限于此,在文章的開始我們就給大家交代過了,MongoDB底層采用的是“列式存儲(chǔ)”、Json格式數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)的,特別適用于大數(shù)據(jù)量、海量數(shù)據(jù)的存儲(chǔ)以及查詢。故而在下一篇章,我們將往MongoDB塞入40多萬(wàn)(當(dāng)然啦,也可以是百萬(wàn)、千萬(wàn)甚至是億級(jí)別)的數(shù)據(jù),然后再給大家分享一下分頁(yè)查詢和刪除的功能。
好了,本篇文章我們就介紹到這里了,其他相關(guān)的技術(shù),感興趣的小伙伴可以關(guān)注底部Debug的技術(shù)公眾號(hào),或者加Debug的微信,拉你進(jìn)“微信版”的真正技術(shù)交流群!一起學(xué)習(xí)、共同成長(zhǎng)!
補(bǔ)充:
1、本文涉及到的相關(guān)的源代碼可以到此地址,check出來(lái)進(jìn)行查看學(xué)習(xí):
https://gitee.com/steadyjack/SpringBootTechnology
2、最近Debug發(fā)布了幾門重量級(jí)的課程,感興趣的小伙伴可以前往觀看學(xué)習(xí):
(1)
緩存中間件Redis技術(shù)入門與應(yīng)用場(chǎng)景實(shí)戰(zhàn)(SpringBoot2.x + 搶紅包系統(tǒng)設(shè)計(jì)與實(shí)戰(zhàn))
https://www.fightjava.com/web/index/course/detail/12
(2)
企業(yè)權(quán)限管理平臺(tái)(SpringBoot2.0+Shiro+Vue+Mybatis)
https://www.fightjava.com/web/index/course/detail/8