Fastify
@fastify/mongodb
- 是 Fastify 框架的一个插件,用来连接 MongoDB,并提供数据库的操作接口。
- 它本质上是一个数据库驱动工具,类似于 MongoDB 的官方驱动
- 它并不算一个传统意义上的 ORM,因为 ORM(如 Sequelize、Mongoose 等)通常是用来
- 在关系型数据库中实现对象与数据库表之间的映射
ajv
- 是一个用于验证 JavaScript 对象的工具,基于 JSON Schema 进行数据校验
- 它的作用是确保传入的数据符合某个预定义的格式、类型或结构。
ORM
- ORM
- 它通过将对象(通常是类实例)与数据库表进行映射,简化了数据库操作的过程。
- ORM 主要用于处理关系型数据的模式,能够自动将对象的属性和表的字段进行一一映射,从而实现对象与数据库之间的相互转换。
- NoSQL
- NoSQL 数据库通常不需要传统意义上的 ORM
- 没有表的概念:
- NoSQL 数据库如 MongoDB 使用集合(Collection)而不是表。
- 每个文档是一个 JSON 对象,数据结构较为灵活,通常没有固定的模式(Schema)。
- 没有外键和关系:
- 关系型数据库的 ORM 需要处理表之间的关系(如一对多、多对多等),
- 而 NoSQL 数据库则更强调数据的独立性和灵活性,通常不涉及复杂的关系管理。
- 尽管没有传统的 ORM,NoSQL 数据库中仍然有类似的工具,这些工具帮助开发者以对象的方式进行数据建模,
- 但它们的实现方式与关系型数据库的 ORM 不完全相同。
Mongoose
- Mongoose (MongoDB):
- 虽然 MongoDB 是 NoSQL 数据库,
- Mongoose 提供了一种面向对象的数据建模方式,使得开发者能够定义“模型”和“文档”之间的映射,并且通过对象的方式与数据库交互。
- Mongoose 类似于 ORM,但它并不处理Mongoose关系(因为 MongoDB 本身不强调关系),而是更多地帮助开发者规范数据结构和操作。
Schema
- 是数据的结构化描述,通常包括字段的类型、关系、约束和验证规则
- 在 ORM(如 Mongoose、Sequelize、TypeORM 等)中,Schema 是定义数据模型的地方
- AJV 是一个用于 JSON 数据验证的库,它也使用 Schema 来描述数据的结构和验证规则
- 在关系型数据库(如 MySQL、PostgreSQL 等)中,Schema 通常指的是数据库中的表结构,包括表名、字段名称、字段类型、约束(如主键、外键、唯一性等)
开发实践
@fastify/mongodb 对比 Mongoose
- @fastify/mongodb
- 手动编写查询语句
- 无数据模型,字段和值通过代码手动管理
- 需要手动处理数据验证和类型转换
- Mongoose
- 使用 Mongoose 模型,简化数据库操作与查询
- 使用 Schema 定义模型,自动验证数据结构
- Mongoose 自动处理数据验证、类型转换等(自带内建验证机制)
- Mongoose 提供更强的查询、聚合和关联操作功能
- 提供丰富的功能,例如中间件、钩子、虚拟字段等
- 关联查询:
- @fastify/mongodb 不提供内建的关联查询功能,你需要手动进行多次查询或使用聚合管道进行关联操作。这意味着,使用 @fastify/mongodb 可能会让代码变得更加冗长和复杂,尤其是涉及多个集合(表)之间的查询时。
- Mongoose 支持 关联查询(如 populate())来处理 MongoDB 中的引用(ObjectId)。你可以通过 Mongoose 快速实现关联查询和嵌套文档操作。
mongoose 在@fastify/mongodb基础上连接数据库
js
const fastify = require('fastify')();
const fastifyMongodb = require('@fastify/mongodb');
const mongoose = require('mongoose');
// 注册 @fastify/mongodb 插件
fastify.register(fastifyMongodb, {
url: 'mongodb://localhost:27017/mydb' // MongoDB 连接
});
// 获取 Fastify 注入的 MongoDB 连接
const db = fastify.mongo.client;
// 使用 Mongoose 连接这个 MongoDB 客户端
mongoose.connect(db.s.url, { useNewUrlParser: true, useUnifiedTopology: true });
// 定义 Mongoose 模型
const itemSchema = new mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true }
});
const Item = mongoose.model('Item', itemSchema);
// 路由:获取所有文档
fastify.get('/items', async (request, reply) => {
try {
const items = await Item.find(); // 使用 Mongoose 查询数据
reply.send(items);
} catch (err) {
reply.status(500).send({ error: 'Failed to fetch items' });
}
});
// 启动服务器
fastify.listen(3000, err => {
if (err) {
console.error(err);
process.exit(1);
}
console.log('Server listening on http://localhost:3000');
});
- db.s.url 是 Fastify 插件 @fastify/mongodb 提供的 MongoDB 客户端实例
- (通常是 fastify.mongo.client)中的 url 属性,它存储了 MongoDB 连接字符串(与第一种方式中的 URI 是一样的)。
- 因为 db.s.url 本质上是连接 MongoDB 的 URI,因此 mongoose.connect(db.s.url, {...}) 是在使用相同的连接字符串进行连接。
- 它们是通过相同的 MongoDB URI 创建连接,且在 Mongoose 中,如果在同一实例中调用 mongoose.connect() 多次,它会自动管理连接并且只会创建一个连接。
migrate-mongo
- 官方推荐,MongoDB迁移工具,使用 JS 文件定义升级/降级脚本