一、MongoDB簡介
1.1 MongoDB介紹
MongoDB是一個強大、靈活,且易於擴充套件的通用型資料庫。MongoDB是C++編寫的文件型資料庫,有著豐富的關係型資料庫的功能,並在4.0之後新增了事務支援。
隨著儲存資料量不斷的增加,開發者面臨一個困難:如何擴充套件資料庫?而擴充套件資料庫分為橫向擴充套件和縱向擴充套件,縱向擴充套件就是使用計算能力更強大的機器,它的缺點就是:機器效能的提升有物理極限的制約,而且大型機通常都是非常昂貴的,而MongoDB的設計採用的是橫向擴充套件的模式,面向文件的資料模型使它很容易的在多臺伺服器上進行資料分割。MongoDB能自動處理誇叢集的資料和負載,自動重新分配文件,這樣開發者就能集中精力編寫應用程式,而不需要考慮如果擴充套件的問題。
1.2 MongoDB安裝
MongoDB的安裝簡單來說分為兩種:
- 官網下載對應物理機的安裝包,直接安裝
- 使用Docker映象,安裝到Docker上
推薦使用第二種,直接使用MongoDB映象安裝到Docker上,這樣帶來的好處是:
- 安裝簡單、方便,且快速
- 更容易進行資料遷移,使用Docker可以很容易的匯入和匯出整個MongoDB到任何地方
所以本文將重點介紹MongoDB在Docker上的安裝和使用。
如果想要直接在物理機安裝Docker,可以檢視我之前的一篇文章《MongoDB基礎介紹安裝與使用》:www.cnblogs.com/vipstone/p/…
1.3 Docker上安裝MongoDB
在Docker上安裝軟體一般需要兩步:
- pull(下載)對應的映象(相對於下載軟體)
- 裝載映象到容器(相對於安裝軟體)
1.3.1 下載映象
下載映象,需要到映象市場:hub.docker.com/,如要要搜尋的軟體“m…
docker pull mongo:latest
1.3.2 裝載映象到容器
使用命令:
docker run --name mongodb1 -p 27018:27017 -d mongo:latest
- --name 指定容器名稱
- -p 27018:27017 對映本地埠27018到容器埠27017
- -d 後臺執行
- mongo:latest 映象名稱和標籤
使用“docker images”檢視映象名稱和標籤,如下圖:
容器裝載成功之後,就可以使用Robo 3T客戶端進行連線了,是不需要輸入使用者名稱和密碼的,如下圖:
表示已經連線成功了。
Robo 3T為免費的連線MongoDB的資料庫工具,可以去官網下載:robomongo.org/download
1.3.3 開啟身份認證
如果是生成環境,沒有使用者名稱和密碼的MongoDB是非常不安全的,因此我們需要開啟身份認證。
Setp1:裝載容器
我們還是用之前下載的映象,重新裝載一個容器例項,命令如下:
docker run --name mongodb2 -p 27019:27017 -d mongo:latest --auth
其中“--auth”就是開啟身份認證。
裝載完身份認證成功容器之後,我們需要進入容器內部,給MongoDB設定使用者名稱和密碼。
Setp2:進入容器內部
docker exec -it <容器id/名稱> bash
Setp3:進入mongo命令列模式
mongo admin
Setp4:建立使用者
db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });
建立的使用者名稱為“admin”密碼為“admin”,指定的資料庫為“admin”。
這個時候,我們使用Robo 3T 輸入相應的資訊進行連線,如下圖:
表示已經連線成功了。
1.3.4 建立資料庫設定使用者
上面我們用“admin”賬戶使用了系統資料庫“admin”,通常在生成環境我們不會直接使用系統的資料庫,這個時候我們需要自己建立自己的資料庫分配相應的使用者。
Setp1:首先需要進入容器
docker exec -it <容器id/名稱> bash
Setp2:建立資料庫
use testdb
如果沒有testdb就會自動建立資料庫。
Setp3:建立使用者分配資料庫
db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "readWrite", db: "testdb" } ] });
其中 role: "readWrite" 表式給使用者賦值操作和讀取的許可權,當然增加索引、刪除表什麼的也是完全沒有問題的。
到目前為止我們就可以使用admin/admin操作testdb資料庫了。
1.3.5 其他Docker命令
刪除容器:docker container rm <容器id/名稱>
停止容器:docker stop <容器id/名稱>
啟動容器:docker start <容器id/名稱>
檢視執行是容器:docker ps
查詢所有的容器:docker ps -a
二、MyBatis整合MongoDB
Spring Boot專案整合MyBatis前兩篇文章已經做了詳細的介紹,這裡就不做過多的介紹,本文重點來介紹MongoDB的整合。
Setp1:新增依賴
在pom.xml新增如下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
複製程式碼
Setp2:配置MongoDB連線
在application.properties新增如下配置:
spring.data.mongodb.uri=mongodb://username:pwd@172.16.10.79:27019/testdb
複製程式碼
Setp3:建立實體類
import java.io.Serializable;
public class User implements Serializable {
private Long id;
private String name;
private int age;
private String pwd;
//...略set、get
}
複製程式碼
Setp4:建立Dao類
import com.hello.springboot.entity.User;
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.Component;
import java.util.List;
@Component
public class UserDao {
@Autowired
private MongoTemplate mongoTemplate;
/**
* 新增使用者
* @param user User Object
*/
public void insert(User user) {
mongoTemplate.save(user);
}
/**
* 查詢所有使用者
* @return
*/
public List<User> findAll() {
return mongoTemplate.findAll(User.class);
}
/**
* 根據id 查詢
* @param id
* @return
*/
public User findById(Long id) {
Query query = new Query(Criteria.where("id").is(id));
User user = mongoTemplate.findOne(query, User.class);
return user;
}
/**
* 更新
* @param user
*/
public void updateUser(User user) {
Query query = new Query(Criteria.where("id").is(user.getId()));
Update update = new Update().set("name", user.getName()).set("pwd", user.getPwd());
mongoTemplate.updateFirst(query, update, User.class);
}
/**
* 刪除物件
* @param id
*/
public void deleteUserById(Long id) {
Query query = new Query(Criteria.where("id").is(id));
mongoTemplate.remove(query, User.class);
}
}
複製程式碼
Setp4:建立Controller
import com.hello.springboot.dao.IndexBuilderDao;
import com.hello.springboot.dao.UserDao;
import com.hello.springboot.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@RestController
@RequestMapping("/")
public class UserController {
@Autowired
private UserDao userDao;
@RequestMapping("/")
public ModelAndView index() {
User user = new User();
user.setId(new Long(1));
user.setAge(18);
user.setName("Adam");
user.setPwd("123456");
userDao.insert(user);
ModelAndView modelAndView = new ModelAndView("/index");
modelAndView.addObject("count", userDao.findAll().size());
return modelAndView;
}
}
複製程式碼
Setp5:建立頁面程式碼
<html>
<head>
<title>王磊的部落格</title>
</head>
<body>
Hello ${count}
</body>
</html>
複製程式碼
到此為止已經完成了MongoDB的整合,啟動專案,輸入“http://localhost:8080/”去資料庫檢視插入的資料吧。
正常插入資料庫如下圖:
三、MongoDB主鍵自增
細心的使用者可能會發現,雖然MongoDB已經整合完了,但插入資料庫的時候user的id是手動set的值,接下來我們來看怎麼實現MongoDB中的id自增。
3.1 實現思路
MongoDB 實現id自增和Spring Boot JPA類似,是在資料庫建立一張表,來記錄表的“自增id”,只需要保證每次都增加的id和返回的id的原子性,就能保證id實現“自增”的功能。
3.2 實現方案
有了思路之後,接下來我們來看具體的實現方案。
3.2.1 建立實體類
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "IndexBuilder")
public class IndexBuilder {
@Id
private String id;
private Long seq;
//..省略get、set方法
}
複製程式碼
其中collection = "IndexBuilder"是指資料庫的集合名稱,對應關係型資料庫的表名。
3.2.2 建立Dao類
import com.hello.springboot.entity.IndexBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Component
public class IndexBuilderDao {
@Autowired
private MongoOperations mongo;
/**
* 查詢下一個id
* @param collectionName 集合名
* @return
*/
public Long getNextSequence(String collectionName) {
IndexBuilder counter = mongo.findAndModify(
query(where("_id").is(collectionName)),
new Update().inc("seq", 1),
options().returnNew(true).upsert(true),
IndexBuilder.class);
return counter.getSeq();
}
}
複製程式碼
3.2.3 使用“自增”的id
User user = new User();
user.setId(indexBuilderDao.getNextSequence("user"));
//...其他設定
複製程式碼
核心程式碼:indexBuilderDao.getNextSequence("user") 使用“自增”的id,實現id自增。
到此為止,已經完成了MongoDB的自增功能,如果使用正常,資料庫應該是這樣的:
資料庫的IndexBuilder就是用來記錄每個集合的“自增id”的。
MongoDB整合的原始碼:github.com/vipstone/sp…