You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS实现动态Sequelize数据库连接与指定库数据查询

在NestJS中实现Sequelize动态数据库连接与查询接口

核心思路

预先初始化多个数据库连接,通过接口传入的参数选择对应连接,复用相同模型完成数据查询。这种方式避免了频繁创建/销毁连接的性能损耗,同时保证模型逻辑的一致性。


1. 配置多数据库连接

首先定义两个数据库的配置,并创建对应的Sequelize连接实例。

1.1 数据库配置文件

创建src/database/database.config.ts(结合@nestjs/config管理环境变量):

import { ConfigService } from '@nestjs/config';

export const getDbConfig = (configService: ConfigService, dbPrefix: string) => ({
  dialect: 'mysql', // 根据实际数据库类型调整
  host: configService.get(`${dbPrefix}_HOST`),
  port: configService.get(`${dbPrefix}_PORT`),
  username: configService.get(`${dbPrefix}_USER`),
  password: configService.get(`${dbPrefix}_PASSWORD`),
  database: configService.get(`${dbPrefix}_NAME`),
});

1.2 连接Provider

创建src/database/database.providers.ts,初始化两个数据库连接:

import { Sequelize } from 'sequelize-typescript';
import { ConfigService } from '@nestjs/config';
import { getDbConfig } from './database.config';
import { User } from '../user/user.model'; // 共享模型

export const databaseProviders = [
  {
    provide: 'SEQUELIZE_DB1',
    useFactory: (configService: ConfigService) => {
      const sequelize = new Sequelize(getDbConfig(configService, 'DB1'));
      sequelize.addModels([User]);
      return sequelize;
    },
    inject: [ConfigService],
  },
  {
    provide: 'SEQUELIZE_DB2',
    useFactory: (configService: ConfigService) => {
      const sequelize = new Sequelize(getDbConfig(configService, 'DB2'));
      sequelize.addModels([User]);
      return sequelize;
    },
    inject: [ConfigService],
  },
];

1.3 数据库模块

创建src/database/database.module.ts,导出连接供其他模块使用:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { databaseProviders } from './database.providers';

@Module({
  imports: [ConfigModule.forRoot()],
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}

2. 定义共享模型

创建通用模型src/user/user.model.ts,无需指定固定连接:

import { Table, Column, Model, DataType } from 'sequelize-typescript';

@Table({ tableName: 'users' })
export class User extends Model<User> {
  @Column({ type: DataType.INTEGER, primaryKey: true, autoIncrement: true })
  id: number;

  @Column({ type: DataType.STRING })
  name: string;

  @Column({ type: DataType.STRING, unique: true })
  email: string;
}

3. 实现动态查询服务

创建src/user/user.service.ts,根据传入的数据库参数选择对应连接:

import { Injectable, Inject, BadRequestException } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';
import { User } from './user.model';

export enum DbName {
  DB1 = 'db1',
  DB2 = 'db2',
}

@Injectable()
export class UserService {
  private readonly dbMap: Record<DbName, Sequelize>;

  constructor(
    @Inject('SEQUELIZE_DB1') private readonly sequelizeDb1: Sequelize,
    @Inject('SEQUELIZE_DB2') private readonly sequelizeDb2: Sequelize,
  ) {
    this.dbMap = {
      [DbName.DB1]: sequelizeDb1,
      [DbName.DB2]: sequelizeDb2,
    };
  }

  // 验证并获取数据库连接
  private getDbConnection(dbName: string): Sequelize {
    const validDbName = dbName as DbName;
    const connection = this.dbMap[validDbName];
    if (!connection) {
      throw new BadRequestException('无效的数据库标识,仅支持 db1/db2');
    }
    return connection;
  }

  // 查询所有用户
  async getUsers(dbName: string): Promise<User[]> {
    const sequelize = this.getDbConnection(dbName);
    const UserModel = sequelize.model<User>(User.name);
    return UserModel.findAll();
  }

  // 根据ID查询用户
  async getUserById(dbName: string, id: number): Promise<User> {
    const sequelize = this.getDbConnection(dbName);
    const UserModel = sequelize.model<User>(User.name);
    const user = await UserModel.findByPk(id);
    if (!user) {
      throw new BadRequestException('用户不存在');
    }
    return user;
  }

  // 模块初始化时验证连接
  async onModuleInit() {
    await Promise.all(
      Object.values(this.dbMap).map((conn) => conn.authenticate()),
    );
  }
}

4. 暴露查询接口

创建src/user/user.controller.ts,接收数据库参数并调用服务:

import { Controller, Get, Param, Query, ValidationPipe } from '@nestjs/common';
import { UserService, DbName } from './user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  async getUsers(
    @Query('db', new ValidationPipe({ transform: true })) dbName: DbName,
  ) {
    return this.userService.getUsers(dbName);
  }

  @Get(':id')
  async getUserById(
    @Query('db', new ValidationPipe({ transform: true })) dbName: DbName,
    @Param('id') id: number,
  ) {
    return this.userService.getUserById(dbName, id);
  }
}

4.1 用户模块

创建src/user/user.module.ts,整合服务与控制器:

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  imports: [DatabaseModule],
  providers: [UserService],
  controllers: [UserController],
})
export class UserModule {}

4.2 根模块

在src/app.module.ts中导入用户模块:

import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';

@Module({
  imports: [UserModule],
})
export class AppModule {}

接口调用示例

  • 查询db1的所有用户:GET /users?db=db1
  • 查询db2中ID为1的用户:GET /users/1?db=db2

内容的提问来源于stack exchange,提问作者RJ amal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:50:30