MongoDB
在这一章节中,我们选择 Typegoose 作为基础的 MongoDB ORM 库。就如同他描述的那样 " Define Mongoose models using TypeScript classes",和 TypeScript 结合的很不错。
简单的来说,Typegoose 使用 TypeScript 编写 Mongoose 模型的 “包装器”,它的大部分能力还是由 mongoose 库来提供的。
也可以直接选择 mongoose 库来使用,我们会分别描述。
Mongoose 版本依赖
mongoose 和你服务器使用的 MongoDB Server 的版本也有着一定的关系,如下,请务必注意。
- MongoDB Server 2.4.x: mongoose ^3.8 or 4.x
- MongoDB Server 2.6.x: mongoose ^3.8.8 or 4.x
- MongoDB Server 3.0.x: mongoose ^3.8.22, 4.x, or 5.x
- MongoDB Server 3.2.x: mongoose ^4.3.0 or 5.x
- MongoDB Server 3.4.x: mongoose ^4.7.3 or 5.x
- MongoDB Server 3.6.x: mongoose 5.x
- MongoDB Server 4.0.x: mongoose ^5.2.0
- MongoDB Server 4.2.x: mongoose ^5.7.0
- MongoDB Server 4.4.x: mongoose ^5.10.0
- MongoDB Server 5.x: mongoose ^6.0.0
mongoose 相关的依赖比较复杂,且对应不同的版本,现阶段,我们使用的主要是 mongoose v5 和 v6。
从 mongoose@v5.11.0 开始,mongoose 官方支持了定义,所以不再需要安装 @types/mongoose 依赖包。
安装包依赖版本如下:
支持 MongoDB Server 5.x
"dependencies": {
"mongoose": "^6.0.7",
"@typegoose/typegoose": "^9.0.0", // 使用 typegoose 需要安装此依赖
},
支持 MongoDB Server 4.4.x
以下版本不需要安装额外定义包。
"dependencies": {
"mongoose": "^5.13.3",
"@typegoose/typegoose": "^8.0.0", // 使用 typegoose 需要安装此依赖
},
以下版本需要安装额外定义包(不推荐)。
"dependencies": {
"mongodb": "3.6.3", // mongoose 内部写死了该版本
"mongoose": "~5.10.18",
"@typegoose/typegoose": "^7.0.0", // 使用 typegoose 需要安装此依赖
},
"devDependencies": {
"@types/mongodb": "3.6.3", // 只能使用此版本
"@types/mongoose": "~5.10.3",
}
其余的 MongoDB 安装模块类似,未测。
使用 Typegoose
1、安装组件
安装 Typegoose 组件,提供访问 MongoDB 的能力。
请务必注意,请查看第一小节提前编写/安装 mongoose 等相关依赖包。
$ npm i @midwayjs/typegoose@2 --save
安装后需要手动在 src/configuration.ts 配置,代码如下。
// configuration.ts
import { Configuration } from '@midwayjs/decorator';
import * as typegoose from '@midwayjs/typegoose';
@Configuration({
imports: [
typegoose, // 加载 typegoose 组件
],
importConfigs: [join(__dirname, './config')],
})
export class ContainerConfiguration {}
在该组件中,midway 只是做了简单的配置规则化,并将其注入到初始化流程中。
2、配置连接信息
在 src/config/config.default.ts 中加入 连接的配置。
export const mongoose = {
client: {
uri: 'mongodb://localhost:27017/test',
options: {
useNewUrlParser: true,
useUnifiedTopology: true,
user: '***********',
pass: '***********',
},
},
};
3、简单的目录结构
我们以一个简单的项目举例,其他结构请自行参考。
MyProject
├── src // TS 根目录
│ ├── config
│ │ └── config.default.ts // 应用配置文件
│ ├── entity // 实体(数据库 Model) 目录
│ │ └── user.ts // 实体文件
│ ├── configuration.ts // Midway 配置文件
│ └── service // 其他的服务目录
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json
在这里,我们的数据库实体主要放在 entity 目录(非强制),这只是一个简单的约定。
3、创建实体文件
import { prop } from '@typegoose/typegoose';
import { EntityModel } from '@midwayjs/typegoose';
@EntityModel()
export class User {
@prop()
public name?: string;
@prop({ type: () => [String] })
public jobs?: string[];
}
等价于使用 mongoose 的下列代码
const userSchema = new mongoose.Schema({
name: String,
jobs: [{ type: String }],
});
const User = mongoose.model('User', userSchema);
所以说,typegoose 只是简化了 model 的创建过程。