MongoDB:原來我如此簡單
為什麼要使用 MongoDB
-
張三大學畢業設計題目是《XXX部落格論壇》,他在存儲用戶評論的時候遇到了一個問題:這些評論數據量非常大,但是價值不是很大,如果存儲在 MySQL 資料庫中就會浪費性能。
-
李四在工作過程中遇到一個需求:在審批模組中,每一個公司都可以自定義請假類型,例如調休、出差等。相當於給每個公司維護一個自己的數據字典。
張三的痛點是存儲的部落格評論數據量大但是價值不大,不適合使用Mysql存儲。李四的痛點是需要維護一個數據字典,不適合用關係型數據局。為了解決張三和李四的痛點,這個時候非關係型文檔型資料庫 MongoDB 閃亮登場。
MongoDB 介紹
1. 什麼是 MongoDB
MongoDB是一個跨平台的,面向文檔的資料庫,是當前NoSQL資料庫產品中最熱門的一種。它介於關係資料庫和非關係資料庫之間,是非關係資料庫當中功能最豐富,最像關係資料庫的產品。
2. MongoDB 特點
MongoDB 最大的特點是他支援的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支援對數據建立索引。它是一個面向集合的,模式自由的文檔型資料庫。具體特點總結如下:
(1)面向集合存儲,易於存儲對象類型的數據
(2)模式自由
(3)支援動態查詢
(4)支援完全索引,包含內部對象
(5)支援複製和故障恢復
(6)使用高效的二進位數據存儲,包括大型對象(如影片等)
(7)支援 Python,Java,C,Javascript,Perl及 C++ 語言的驅動程式
(9)文件存儲格式為 BSON(一種 JSON 的擴展)
3. MongoDB 結構
MongoDB 的邏輯結構是一種層次結構。主要由:文檔 (document)、集合(collection)、資料庫 (database) 這三部分組成的。
(1)MongoDB 的文檔,相當於關係資料庫中的一行記錄。
(2)多個文檔組成一個集合,集合相當於關係資料庫的表。
(3)多個集合邏輯上組織在一起,就是資料庫。
4. MongoDB 與 MySQL 資料庫邏輯結構概念的對比
MongoDB | MySQl |
---|---|
資料庫(database) | 資料庫(database) |
集合(Collection | 表(table) |
文檔(document) | 行(row) |
主鍵,MongoDB默認將_id設為主鍵 | 主鍵 |
索引 | 索引 |
5.MongoDB 層次結構如下圖
安裝 MongoDB
1. Docker安裝MongoDB
啟動MongoDB服務
docker run -itd --name mongo -p 27017:27017 mongo --auth
註:1. 如果是購買的伺服器,請將安全組的27017埠打開。 2. -p 27017:27017 :容器服務的 27017 埠映射到伺服器的27017埠。外部可以直接通過伺服器 ip:27017 訪問到 mongodb 的服務。
–auth:需要密碼才能訪問。
2. 創建賬戶
##進入到容器內部
docker exec -it mongo mongo admin
##創建系統管理員
db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
##驗證賬戶密碼
db.auth('admin', '123456')
##創建其他資料庫
use ems
##在該資料庫下創建其他賬戶
db.createUser({ user: 'root', pwd: 'abc123456', roles: [ { role: "readWrite", db:"ems" } ] });
##驗證賬戶密碼
db.auth('root', 'abc123456')
3. Navicat 客戶端連接 MongoDB
創建資料庫
SpringBoot 整合 MongoDB
1. 添加依賴
<!-- MongoDB-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2. 修改 SpringBoot 配置文件
spring:
data:
mongodb:
uri: mongodb://root:123456@localhost:27017/test
賬戶:root
密碼:123456
資料庫:test
3. 創建實體類
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* 常用收款人
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Document(collection = "common_account")
public class CommonAccount {
@Id
private String id;
//公司id
private Integer companyId;
//付款人
private String payer;
//銀行
private String bank;
//分支行
private String bankBranch;
//帳號
private String bankNum;
}
關鍵註解:1. @Document(collection = “common_account”)
@Document表示這是一個集合,當你保存數據的時候如果你沒有創建集合,他會自動給你創建一個名為 common_account 的集合。2. @Id:隨機生成id
4. 創建 Repository
@Repository
public interface CommonAccountRepository extends MongoRepository<CommonAccount, String> {
//獲取該公司的所有常用收款人賬戶
List<CommonAccount> getByCompanyId(Integer companyId);
}
extends MongoRepository:通過繼承 MongoRepository 可以使用它很多常用的方法。
5. 創建 Service
public interface CommonAccountService {
//獲取該公司的收款賬戶
List<CommonAccount> getCommonAccount(Integer companyId);
//添加收款賬戶
void addCommonAccount(CommonAccount commonAccount);
//更新收款賬戶
void updateCommonAccount(CommonAccount commonAccount);
//刪除收款賬戶
void deleteCommonAccount(String id);
}
6. Service 實現類
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommonAccountServiceImpl implements CommonAccountService {
@Autowired
private CommonAccountRepository commonAccountRepository;
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List<CommonAccount> getCommonAccount(Integer companyId) {
List<CommonAccount> accountList = commonAccountRepository.getByCompanyId(companyId);
return accountList;
}
@Override
public void addCommonAccount(CommonAccount commonAccount) {
commonAccountRepository.save(commonAccount);
}
@Override
public void updateCommonAccount(CommonAccount commonAccount) {
Query query = Query.query(Criteria.where("id").is(commonAccount.getId()));
Update update = new Update();
update.set("companyId", commonAccount.getCompanyId());
update.set("payer", commonAccount.getPayer());
update.set("bank", commonAccount.getBank());
update.set("bankBranch", commonAccount.getBankBranch());
update.set("bankNum", commonAccount.getBankNum());
mongoTemplate.updateFirst(query, update, CommonAccount.class);
}
@Override
public void deleteCommonAccount(String id) {
commonAccountRepository.deleteById(id);
}
}
7. 去除 _class 列
mongoDB 保存數據的時候默認會新增一個 _class 列,如下圖:
添加如下配置,去除_class 列
@Configuration
public class MongoConfig {
/**
* 去掉_class
* @param factory
* @param context
* @param beanFactory
* @return
*/
@Bean
public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
try {
mappingConverter.setCustomConversions(beanFactory.getBean(MongoCustomConversions.class));
} catch (NoSuchBeanDefinitionException ignore) {
}
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingConverter;
}
}
8. 測試
@Test
void mongoTest() {
CommonAccount commonAccount = new CommonAccount();
commonAccount.setPayer("張三").setBank("交通銀行").setBankBranch("北京路分行")
.setBankNum("61262663265362").setCompanyId(100);
commonAccountService.addCommonAccount(commonAccount);
}