Spring Boot (八)MyBatis + Docker + MongoDB 4.x

一、MongoDB簡介

1.1 MongoDB介紹

MongoDB是一個強大、靈活,且易于擴展的通用型數(shù)據(jù)庫。MongoDB是C++編寫的文檔型數(shù)據(jù)庫,有著豐富的關(guān)系型數(shù)據(jù)庫的功能,并在4.0之后添加了事務(wù)支持。

隨著存儲數(shù)據(jù)量不斷的增加,開發(fā)者面臨一個困難:如何擴展數(shù)據(jù)庫?而擴展數(shù)據(jù)庫分為橫向擴展和縱向擴展,縱向擴展就是使用計算能力更強大的機器,它的缺點就是:機器性能的提升有物理極限的制約,而且大型機通常都是非常昂貴的,而MongoDB的設(shè)計采用的是橫向擴展的模式,面向文檔的數(shù)據(jù)模型使它很容易的在多臺服務(wù)器上進行數(shù)據(jù)分割。MongoDB能自動處理夸集群的數(shù)據(jù)和負載,自動重新分配文檔,這樣開發(fā)者就能集中精力編寫應(yīng)用程序,而不需要考慮如果擴展的問題。

1.2 MongoDB安裝

MongoDB的安裝簡單來說分為兩種:

  • 官網(wǎng)下載對應(yīng)物理機的安裝包,直接安裝
  • 使用Docker鏡像,安裝到Docker上

推薦使用第二種,直接使用MongoDB鏡像安裝到Docker上,這樣帶來的好處是:

  • 安裝簡單、方便,且快速
  • 更容易進行數(shù)據(jù)遷移,使用Docker可以很容易的導(dǎo)入和導(dǎo)出整個MongoDB到任何地方

所以本文將重點介紹MongoDB在Docker上的安裝和使用。

如果想要直接在物理機安裝Docker,可以查看我之前的一篇文章《MongoDB基礎(chǔ)介紹安裝與使用》:https://www.cnblogs.com/vipstone/p/8494347.html

1.3 Docker上安裝MongoDB

在Docker上安裝軟件一般需要兩步:

  1. pull(下載)對應(yīng)的鏡像(相對于下載軟件)
  2. 裝載鏡像到容器(相對于安裝軟件)

1.3.1 下載鏡像

下載鏡像,需要到鏡像市場:https://hub.docker.com/,如要要搜索的軟件“mongo”,選擇官方鏡像“Official”,點擊詳情,獲取相應(yīng)的下載方法,我們得到下載MongoDB的命令如下:

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 鏡像名稱和標(biāo)簽

使用“docker images”查看鏡像名稱和標(biāo)簽,如下圖:

image

容器裝載成功之后,就可以使用Robo 3T客戶端進行連接了,是不需要輸入用戶名和密碼的,如下圖:

image

表示已經(jīng)連接成功了。

Robo 3T為免費的連接MongoDB的數(shù)據(jù)庫工具,可以去官網(wǎng)下載:https://robomongo.org/download

1.3.3 開啟身份認證

如果是生成環(huán)境,沒有用戶名和密碼的MongoDB是非常不安全的,因此我們需要開啟身份認證。

Setp1:裝載容器

我們還是用之前下載的鏡像,重新裝載一個容器實例,命令如下:

docker run --name mongodb2 -p 27019:27017 -d mongo:latest --auth

其中“--auth”就是開啟身份認證。

裝載完身份認證成功容器之后,我們需要進入容器內(nèi)部,給MongoDB設(shè)置用戶名和密碼。

Setp2:進入容器內(nèi)部

docker exec -it <容器id/名稱> bash

Setp3:進入mongo命令行模式

mongo admin

Setp4:創(chuàng)建用戶

db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });

創(chuàng)建的用戶名為“admin”密碼為“admin”,指定的數(shù)據(jù)庫為“admin”。

這個時候,我們使用Robo 3T 輸入相應(yīng)的信息進行連接,如下圖:

image

表示已經(jīng)連接成功了。

1.3.4 創(chuàng)建數(shù)據(jù)庫設(shè)置用戶

上面我們用“admin”賬戶使用了系統(tǒng)數(shù)據(jù)庫“admin”,通常在生成環(huán)境我們不會直接使用系統(tǒng)的數(shù)據(jù)庫,這個時候我們需要自己創(chuàng)建自己的數(shù)據(jù)庫分配相應(yīng)的用戶。

Setp1:首先需要進入容器

docker exec -it <容器id/名稱> bash

Setp2:創(chuàng)建數(shù)據(jù)庫

use testdb

如果沒有testdb就會自動創(chuàng)建數(shù)據(jù)庫。

Setp3:創(chuàng)建用戶分配數(shù)據(jù)庫

db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "readWrite", db: "testdb" } ] });

其中 role: "readWrite" 表式給用戶賦值操作和讀取的權(quán)限,當(dāng)然增加索引、刪除表什么的也是完全沒有問題的。

到目前為止我們就可以使用admin/admin操作testdb數(shù)據(jù)庫了。

1.3.5 其他Docker命令

刪除容器:docker container rm <容器id/名稱>

停止容器:docker stop <容器id/名稱>

啟動容器:docker start <容器id/名稱>

查看運行是容器:docker ps

查詢所有的容器:docker ps -a

二、MyBatis集成MongoDB

Spring Boot項目集成MyBatis前兩篇文章已經(jīng)做了詳細的介紹,這里就不做過多的介紹,本文重點來介紹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:創(chuàng)建實體類

import java.io.Serializable;

public class User implements Serializable {
    private Long id;
    private String name;
    private int age;
    private String pwd;
    //...略set、get
}

Setp4:創(chuàng)建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);
    }

    /**
     * 根據(jù)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:創(chuàng)建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:創(chuàng)建頁面代碼

<html>
<head>
    <title>王磊的博客</title>
</head>
<body>
Hello ${count}
</body>
</html>

到此為止已經(jīng)完成了MongoDB的集成,啟動項目,輸入“http://localhost:8080/”去數(shù)據(jù)庫查看插入的數(shù)據(jù)吧。

正常插入數(shù)據(jù)庫如下圖:

image

三、MongoDB主鍵自增

細心的用戶可能會發(fā)現(xiàn),雖然MongoDB已經(jīng)集成完了,但插入數(shù)據(jù)庫的時候user的id是手動set的值,接下來我們來看怎么實現(xiàn)MongoDB中的id自增。

3.1 實現(xiàn)思路

MongoDB 實現(xiàn)id自增和Spring Boot JPA類似,是在數(shù)據(jù)庫創(chuàng)建一張表,來記錄表的“自增id”,只需要保證每次都增加的id和返回的id的原子性,就能保證id實現(xiàn)“自增”的功能。

3.2 實現(xiàn)方案

有了思路之后,接下來我們來看具體的實現(xiàn)方案。

3.2.1 創(chuàng)建實體類

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"是指數(shù)據(jù)庫的集合名稱,對應(yīng)關(guān)系型數(shù)據(jù)庫的表名。

3.2.2 創(chuàng)建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"));
//...其他設(shè)置

核心代碼:indexBuilderDao.getNextSequence("user") 使用“自增”的id,實現(xiàn)id自增。

到此為止,已經(jīng)完成了MongoDB的自增功能,如果使用正常,數(shù)據(jù)庫應(yīng)該是這樣的:

image

數(shù)據(jù)庫的IndexBuilder就是用來記錄每個集合的“自增id”的。

MongoDB集成的源碼:https://github.com/vipstone/springboot-example/tree/master/springboot-mybatis-mongodb

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容