SpringBoot 使用 MongoDB 初体验
MongoDB 与 mysql 相比的缺陷
MongoDB 与 mysql 同属于开源阵列,但相较于 mysql,MongoDB 日常项目中接触的不多。但 MongoDB 有它独特的优势,属于 NoSQL 类型的数据库,比较适用于分布式扩展以及大数据运算。
网上提到 MongoDB 主要存在的缺陷:不支持 join 联查,不支持事务操作。MongoDB 的存储单元不同于 mysql 的表,它使用的是 Collection
集合,存储的也不是一行一行的字段数据,而是一个一个的 Document
文档。所以不支持 join 很正常,但 MongoDB 可以通过 lookup 实现多表联查。至于事务操作,百度到也是有其他的实现方式的,比如 SpringBoot @Transactional
注解。
MongoDB 的漏洞
MongoDB 最近(2022年11月)有被爆出存在关键漏洞(CVE-2022-40299),这个漏洞可能允许未授权的攻击者远程执行代码。
漏洞本身升级最新的版本就可以了。并且也通过防火墙规则限制,只允许业务服务器访问,提高安全性。
安装 MongoDB
因为本地 Mac 环境按装了 docker 桌面版,所以优先使用 docker 安装 MongoDB。安装参考:Docker基础:docker 安装mongodb - 腾讯云社区
docker pull mongo[:latest]
后面的 :lastest
可以不加,因为默认就是拉取最新版本。
之后运行镜像容器:
docker run \
-dit \
--name mongo \
--restart=always \
--privileged=true \
-p 27017:27017 \
-v /Users/mac/docker/mongodb/data:/data/db \
mongo:latest --auth
因为 docker 桌面版直接运行容器没办法携带这些参数,所以就从命令行执行,之后再 docker 桌面版容器里可以看到管理启动与停止。
-d
表示以守护进程方式运行,-i
表示以交互模式运行容器,-t
表示为容器分配一个伪终端(pseudo-tty)。-it
这两个参数一起使用可以使得在容器内部进行交互式操作,就像在本地终端中一样。--name mongo
表示指定容器名称。--restart=always
表示启动失败后会一直自动重启。-p 27017:27017
表示将容器的 27017 端口映射到宿主机的 27017 端口,以便外部访问。-v /Users/mac/docker/mongodb/data:/data/db
表示将容器的 /data/db
数据存储文件目录映射到宿主机的 /Users/mac/docker/mongodb/data
目录。宿主机目录在前,可以根据本地环境自定义,:
分隔两个目录。--auth
表示访问 MongoDB 需要用户名和密码。
之后可以通过命令行 docker exec -it mongo /bin/bash
进入容器,也可以桌面版找到 mongo 容器,进入详情,切换到 Exec
容器命令行。
可以使用 mongod --version
查看安装的 mongoDB 版本,当前安装的是 v7.0.7 版本。
登录 mongoDB 的指令发生了变化,不再是 mongo admin
,会报错找不到 mongo 指令。新版为 mongosh admin
,在原指令名称上加了 sh
表示 mongo shell 脚本。这里的 admin 是数据库的名称。授权逻辑发生了变化,mysql 是需要先验证身份,之后访问数据库;mongo 是先连接到数据库,之后再做身份验证。
# mongosh admin
Current Mongosh Log ID: 65fbd627b4034fafbfdb83af
Connecting to: mongodb://127.0.0.1:27017/admin?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.2.0
Using MongoDB: 7.0.7
Using Mongosh: 2.2.0
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
admin>
首次登录是没有账号密码的,需要创建一下:
# 创建一个名为 root,密码为 123456 的用户。猜测后面的角色权限参数应该是给到所有数据库的读写权限。
admin> db.createUser({ user:'root',pwd:'123456',roles:[{ role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
有了 auth 账户,下次再连接数据库,操作 Collection 集合就需要先验证身份了。不然操作会报错:MongoServerError[Unauthorized]: Command createUser requires authentication
admin> db.auth('root', '123456')
{ ok: 1 }
创建集合(表):
db.createCollection('users')
插入数据:
admin> db.users.insert({"name":"小李","age": NumberInt(33)})
查看数据:
admin> db.users.find()
之后就是使用 Navicat 连接 MongoDB 了:
输入连接主机、端口,以及账号密码都没有问题,主要是第一次连接 MongoDB,Navicat 默认会隐藏数据库内容,需要从菜单栏点击查看,勾选显示隐藏的项目。
默认会有三个数据库:admin、config、local,后面两个需要权限才能打开。admin 中应该会有三个表:system.users
系统用户表,上面添加的 root 账号就存储在这里;system.version
系统版本表,以及上面创建的 users 测试表。
搭建 SpringBoot 项目
摘录百度 AI 生成的回答
1. 添加 Maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
因为属于 spring-boot-starter 的版本,所以会根据引入的 spring boot 版本中依赖版本默认安装。其他依赖根据需求自行选择。
2. 配置 MongoDB
在application.properties中添加以下配置:
spring.data.mongodb.uri=mongodb://username:password@localhost:27017/your_database
或者,如果你使用application.yml:
spring:
data:
mongodb:
uri: mongodb://username:password@localhost:27017/your_database
3. 创建实体类
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class YourEntity {
@Id
private String id;
// 其他字段和方法
}
与 mysql 的实体主要在于注解,这里使用的是 @Document
。
4. 创建MongoDB仓库接口
import org.springframework.data.mongodb.repository.MongoRepository;
public interface YourEntityRepository extends MongoRepository<YourEntity, String> {
// 可以自定义查询方法
}
这边也是继承的 repo 不一样。看到还有一种 MongoTemplate 的使用方法,区别在于 template 可以处理更加复杂的查询,比如联合查询等。具体可以查看:SpringBoot中MongoDB的使用 - CSDN。
5. 使用仓库进行操作
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class YourEntityService {
@Autowired
private YourEntityRepository repository;
public YourEntity save(YourEntity entity) {
return repository.save(entity);
}
public YourEntity findById(String id) {
return repository.findById(id).orElse(null);
}
// 其他方法
}