最近几个月在学习鸿蒙知识时需要使用 mongodb,考虑到来回奔波于家和公司之间需要给不同的设备安装 mongodb 来使用,因而选择在服务器上创建 mongodb 容器来解决这个问题
基本使用
创建本地持久存储目录
在文件夹下创建 data、logs、dump 文件夹,在创建 mongodb 容器时进行挂载
1
| mkdir data logs confg dump
|
- data 持久化存储的数据文件夹
- logs 日志文件夹
- dump 备份文件夹
一行命令启动容器
1 2 3 4 5 6 7 8 9
| docker run -it \ --name mongodb \ --restart=always \ --privileged \ -p 27017:27017 \ -v /docker/mongo/data:/data/db \ -v /docker/mongo/dump:/data/dump \ -v /docker/mongo/logs:/data/log \ -d mongo:latest
|
- --name 指定容器名
- --restart=always 自动重新启动
- --privileged 允许容器以特权模式运行
- -p 27017:27017 指定运行端口
- -v 挂载上面创建的持久化文件夹
- -d 后台运行容器
使用 nest 连接 mongodb
创建 nest 项目
nest new project-name 创建项目
安装连接 mongodb 数据库的依赖包
1
| pnpm add @nestjs/mongoose mongoose
|
在 app.modules.ts 中添加数据库配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MongooseModule } from '@nestjs/mongoose'; import { BannerSchema, MenuSchema } from './schemas';
@Module({ imports: [ MongooseModule.forRoot('mongodb://10.10.48.108/mongo'), MongooseModule.forFeature([ { name: 'Banner', schema: BannerSchema, }, { name: 'Menu', schema: MenuSchema, }, ]), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
|
pnpm:start:dev 启动 nest 项目后,通过 MongoDB for VS Code 插件连接启动的 mongodb 容器,就可以看到对应的 banner 和 menu 表了
测试 mongodb
修改 app.controller.ts 文件,创建一个 get 请求使的访问 127.0.0.1 返回查询 banner 表的数据,和一个 post 请求,可以给 banner 表中添加数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import { Controller, Get, Post, Body } from '@nestjs/common'; import { AppService } from './app.service'; import { Banner, HttpResponse } from './types';
@Controller() export class AppController { constructor(private readonly appService: AppService) {}
@Get() async getBanners(): Promise<HttpResponse<Banner[]>> { const data = await this.appService.find(); if (data) { return { code: 1, message: '请求成功', data, }; } } @Post() async addBanner( @Body() addBannerDTO: Banner | Banner[], ): Promise<HttpResponse> { const data = await this.appService.add(addBannerDTO); if (data) { return { code: 1, message: '添加成功', }; } } }
|
修改 app.service.ts 文件,创建一个 find 查询方法和一个 inset 插入方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { Banner } from './types'; @Injectable() export class AppService { constructor(@InjectModel('Banner') private bannerModel: Model<Banner>) {} async find(): Promise<Banner[]> { const data = await this.bannerModel.find().exec(); return data; } async add(addBannerDTO: Banner | Banner[]): Promise<Banner | Banner[]> { if (Array.isArray(addBannerDTO)) { const data = await this.bannerModel.insertMany(addBannerDTO); return data; } else { const data = await new this.bannerModel(addBannerDTO).save(); return data; } } }
|
使用 postman 测试 get 请求
通过 post 接口给数据库添加数据
可以在数据库中看到添加的数据
给 mongodb 添加权限
上述内容已经满足了我们日常本地开发的需要,但部署在服务器上的话,因为没有给 mongodb 添加权限会导致任何人都可以读写数据库,存在很大的安全风险,因而需要添加权限来使用
1 2 3 4 5 6 7 8 9 10 11
| # 启动容器时,添加--auth命令 docker run -it \ --name mongodb \ --restart=always \ --privileged \ -p 27017:27017 \ -v /docker/mongo/data:/data/db \ -v /docker/mongo/dump:/data/dump \ -v /docker/mongo/logs:/data/log \ -d mongo:latest \ --auth
|
开启后重新 get 请求,在命令行中会提示需要授权才可以访问
添加 mongo 表用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # 进入容器 docker exec -ti 容器id /bin/bash # mongosh进入数据库 mongosh # 先在admin中创建root用户 use admin # 创建root用户 db.createUser({user:"root",pwd:"root123",roles:["root"]})
# 授权admin db.auth("root","root1234")
# 创建mongo表用户 use mongo db.createUser({user:"mongo",pwd:"mongo123",roles:[{role:"readWrite",db:"mongo"}]})
|
然后在 MongoDB for VS Code 新建连接,使用 mongodb://mongo:mongo123@10.10.48.108:27017/mongo 连接就可以正常使用了
再修改 nest 中连接 mongodb 的配置为 mongodb://mongo:mongo123@10.10.48.108:27017/mongo,请求也可以正常使用了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MongooseModule } from '@nestjs/mongoose'; import { BannerSchema, MenuSchema } from './schemas';
@Module({ imports: [ MongooseModule.forRoot('mongodb://mongo:mongo123@10.10.48.108:27017/mongo'), MongooseModule.forFeature([ { name: 'Banner', schema: BannerSchema, }, { name: 'Menu', schema: MenuSchema, }, ]), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
|