前言
哪怕作者已经熟悉使用NestJS框架,也没办法仅凭官方文档研究明白Midway3的数据源管理。
因此在这里撰写一份较为通俗易懂的文档讲解一下
介绍
首先稍微介绍一下什么是数据源管理。在Midway和Nest这类框架中,通常都允许同时出现多个/多种数据库链接需求。不同的数据库连接池管理,连接状态,以及用法上都有一定的差异,并不统一。
但是框架本身有提供服务工厂(Service Factory)用来对多实例进行抽象处理。但不管从语义还是功能上,服务工厂都不完全符合数据源管理所需要的。
因此,Midway提供了 DataSourceManager
抽象类,来实现对数据源的管理操作。
实现
先按照正常做法创建一个类文件,这里采用广为人知的 MySQL 数据库做例子, 那么创建一个文件叫 src/manager/mysql.manager.ts
。
继承内置接口
不用多说,继承内置的
DataSourceManager
抽象类,即可实现基础的数据源管理器。当然它包含了一个泛型类型,需要声明这个数据源的连接数据类型。
import { Provide, Scope, ScopeEnum, DataSourceManager } from '@midwayjs/core';
import * as mysql from 'mysql2';
@Provide()
@Scope(ScopeEnum.Singleton)
export class MySqlDataSourceManager extends DataSourceManager<mysql.Connection> {
// ...
}
实现抽象方法
既然是继承的类,那么肯定会有自带的方法需要实现的。这一点应该也无需多讲。
如果觉得到这里都看不明白,你需要进修面向对象的几大特性。
import { Provide, Scope, ScopeEnum, DataSourceManager } from '@midwayjs/core';
import * as mysql from 'mysql2';
@Provide()
@Scope(ScopeEnum.Singleton)
export class MySqlDataSourceManager extends DataSourceManager<mysql.Connection> {
// 创建单个实例
protected async createDataSource(config: any, dataSourceName: string): Promise<mysql.Connection> {
return mysql.createConnection(config);
}
// 返回这个工厂的名字 - 每个工厂名字尽可能不要重复,会导致框架检测异常
getName(): string {
return 'mysql';
}
// 检测实例是否连接上了数据库
async checkConnected(dataSource: mysql.Connection): Promise<boolean> {
// 伪代码 - 因为在mysql2这个库中并没有办法去检查连接状态,所以这里只是一个伪代码
return dataSource.status === 'connected';
}
// 销毁实例
async destroyDataSource(dataSource: mysql.Connection): Promise<void> {
if (await this.checkConnected(dataSource)) {
await dataSource.destroy();
}
}
}
请注意,其中的检查实例状态部分。请自行替换,也可以使用mysql
库代替mysql2
因为一代库中有连接状态检测,在此不多赘述。
检查实例状态示例
protected checkConnected(dataSource: mysql.Connection): Promise<boolean> {
dataSource.connect((err) => {
return Promise.resolve(!err);
});
this.logger.warn(this.i18nService.translate('database.checkConnectionError'));
return Promise.reject();
}
到这里实际上已经创建完毕了,接下来的就跟文档一样走即可