同一个应用程序的 NestJS 使用 TypeORM 模块使用多个连接

问题描述 投票:0回答:1

我们重新编写了 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 参数返回正确的数据源。这是一个好方法吗?是否有人遇到同样的问题并找到另一个更好的解决方案?

nestjs typeorm
1个回答
0
投票

我想你可以做的就是创建返回正确数据源的函数,之后应该很容易避免代码重复。

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]
}
© www.soinside.com 2019 - 2024. All rights reserved.