共计 6321 个字符,预计需要花费 16 分钟才能阅读完成。
一、MongoDB 简介
1.1 MongoDB 介绍
MongoDB 是一个强大、灵活,且易于扩展的通用型数据库。MongoDB 是 C ++ 编写的文档型数据库,有着丰富的关系型数据库的功能,并在 4.0 之后添加了事务支持。
随着存储数据量不断的增加,开发者面临一个困难:如何扩展数据库?而扩展数据库分为横向扩展和纵向扩展,纵向扩展就是使用计算能力更强大的机器,它的缺点就是:机器性能的提升有物理极限的制约,而且大型机通常都是非常昂贵的,而 MongoDB 的设计采用的是横向扩展的模式,面向文档的数据模型使它很容易的在多台服务器上进行数据分割。MongoDB 能自动处理夸集群的数据和负载,自动重新分配文档,这样开发者就能集中精力编写应用程序,而不需要考虑如果扩展的问题。
<!–more–>
1.2 MongoDB 安装
MongoDB 的安装简单来说分为两种:
官网下载对应物理机的安装包,直接安装
使用 Docker 镜像,安装到 Docker 上
推荐使用第二种,直接使用 MongoDB 镜像安装到 Docker 上,这样带来的好处是:
安装简单、方便,且快速
更容易进行数据迁移,使用 Docker 可以很容易的导入和导出整个 MongoDB 到任何地方
所以本文将重点介绍 MongoDB 在 Docker 上的安装和使用。
如果想要直接在物理机安装 Docker,可以查看我之前的一篇文章《MongoDB 基础介绍安装与使用》:https://www.cnblogs.com/vipst…
1.3 Docker 上安装 MongoDB
在 Docker 上安装软件一般需要两步:
pull(下载)对应的镜像(相对于下载软件)
装载镜像到容器(相对于安装软件)
1.3.1 下载镜像
下载镜像,需要到镜像市场:https://hub.docker.com/,如要要搜索的软件“mongo”,选择官方镜像“Official”,点击详情,获取相应的下载方法,我们得到下载 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 镜像名称和标签
使用“docker images”查看镜像名称和标签,如下图:
容器装载成功之后,就可以使用 Robo 3T 客户端进行连接了,是不需要输入用户名和密码的,如下图:
表示已经连接成功了。
Robo 3T 为免费的连接 MongoDB 的数据库工具,可以去官网下载:https://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 集成的源码:https://github.com/vipstone/s…