我们重新编写了 NestJS 的 API。然而,由于业务逻辑的原因,较旧的框架开发人员每次都会复制相同的代码库。因此需要连接到多个包含相似表的数据库。例如,如果一个数据库包含表 user、facility 和 products,则另一个数据库也包含所有这些表。简而言之,每次安装的所有内容都是重复的。当然只是数据库的内容不同。
让我们开始编码吧?为了防止至少代码库的重复,我们尝试创建命名的多个连接,以公司名称命名,即 db_google、db_linkedin 和 url 中定义从池中获取哪个连接的参数
app.module.ts
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
name: 'google',
host: 'our_host_url',
port: 3306,
username: 'username',
password: 'password',
database: 'db_google',
entities: [Facility, FacilityCategory, Customer],
synchronize: false,
}),
TypeOrmModule.forRoot({
type: 'mysql',
name: 'linkedin',
host: 'our_host_url',
port: 3306,
username: 'username',
password: 'password',
database: 'db_linkedin',
entities: [Facility, FacilityCategory, Customer],
synchronize: false,
}),
之后我们将其导入到每个需要从数据库获取数据的模块中(几乎每个模块都导入它)
customer.module.ts
imports: [
TypeOrmModule.forFeature([Customer, Facility], 'db_google'),
TypeOrmModule.forFeature([Customer, Facility], 'db_linkedin'),
],
对于每个 [module].service.ts 中的不同数据库,我们使用 switch case 并使用 url 中的参数来定义要使用的连接
customer.service.ts
constructor(
@InjectDataSource('google')
private dataSourceGoogle: DataSource,
@InjectDataSource('linkedin')
private dataSourceLinkedin: DataSource,
) {}
async findCustomer(
username: string,
companyName: string,
): Promise<Customer | null> {
switch (companyName) {
case 'apollohotels':
return this.dataSourceGoogle.getRepository(Customer).findOneBy({
username: username,
});
case 'saniresort':
return this.dataSourceLinkedin.getRepository(Customer).findOneBy({
username: username,
});
}
}
因此我们想防止重复代码创建一个模块来导入所有这些数据库,例如“ConnectionPool”模块,并将其导入到每个需要从数据库获取数据的模块中。他们的服务根据 companyName 参数返回正确的数据源。这是一个好方法吗?是否有人遇到同样的问题并找到另一个更好的解决方案?
我想你可以做的就是创建返回正确数据源的函数,之后应该很容易避免代码重复。
async findCustomer(
username: string,
companyName: string,
): Promise<Customer | null> {
return this.getDataSource(companyName).getRepository(Customer)
.findOneBy({
username: username,
});
}
getDataSource(companyName: string): DataSource {
const dataSourceMap = {
"apollohotels": this.dataSourceGoogle,
"saniresort": this.dataSourceLinkedin
}
return dataSourceMap[companyName]
}