NestJS + TypeORM 如何启动时动态配置多数据库连接?
在TypeORM中启动时预建立所有动态数据库连接的方案
当然可以在API启动时就预建立所有目标数据库的TypeORM连接,完全解决按需连接带来的请求耗时问题,下面是具体实现方案和注意事项:
1. 批量预建连接
首先需要从配置源(环境变量、配置文件或配置中心)获取所有数据库的连接参数,每个数据库实例对应一个唯一命名的TypeORM连接,然后在API启动阶段批量创建这些连接。
示例代码(TypeScript):
import { createConnection, Connection } from "typeorm"; // 从配置源加载所有数据库配置,这里用数组模拟动态配置 const dynamicDbConfigs = [ { name: "tenant_db_001", type: "mysql", host: "db-host-001", port: 3306, username: "admin", password: "xxx", database: "tenant_001", entities: ["./src/entities/**/*.ts"], synchronize: false, poolSize: 5, // 合理设置连接池大小,避免资源浪费 }, { name: "tenant_db_002", type: "mysql", host: "db-host-002", port: 3306, username: "admin", password: "xxx", database: "tenant_002", entities: ["./src/entities/**/*.ts"], synchronize: false, poolSize: 5, }, // 更多动态生成的数据库配置... ]; // 启动时初始化所有连接 export async function initAllDbConnections(): Promise<Connection[]> { const connections: Connection[] = []; for (const config of dynamicDbConfigs) { try { const conn = await createConnection(config); connections.push(conn); console.log(`Successfully connected to [${config.name}]`); } catch (err) { console.error(`Failed to connect to [${config.name}]:`, err); // 根据业务决定是否终止启动或继续 throw err; } } return connections; } // 在API启动入口调用(比如Express/NestJS的bootstrap) async function bootstrap() { await initAllDbConnections(); // 启动API服务... console.log("API server started with all database connections ready"); } bootstrap();
2. 请求时指定目标数据库
每个连接都有唯一的name标识,请求时通过参数(比如dbName query参数、header或路径参数)指定目标数据库,然后通过getConnection(dbName)获取对应连接,再操作实体仓库。
示例路由(Express):
import { getConnection } from "typeorm"; import { User } from "./entities/User"; app.get("/api/users", async (req, res) => { const { dbName } = req.query; if (!dbName || typeof dbName !== "string") { return res.status(400).json({ error: "Missing or invalid dbName parameter" }); } try { // 获取指定数据库的连接 const dbConn = getConnection(dbName); // 获取实体仓库 const userRepo = dbConn.getRepository(User); // 执行查询 const users = await userRepo.find(); res.json({ data: users }); } catch (err) { if (err.message.includes("ConnectionNotFoundError")) { return res.status(404).json({ error: `Database [${dbName}] not found` }); } res.status(500).json({ error: "Database query failed", details: err.message }); } });
3. 关键注意事项
- 连接池配置:每个连接的
poolSize要根据服务器性能和数据库实例数量合理设置,避免过多连接耗尽系统资源或数据库连接数上限。 - 动态新增数据库:如果运行时会新增数据库实例,可以新增一个管理接口,接收新的数据库配置并调用
createConnection添加连接,注意校验name唯一性。 - 连接健康检查:定期检查连接状态,可监听TypeORM的
connect、disconnect事件,或定时调用conn.isConnected判断,断开时自动重连。 - 资源权衡:如果数据库数量极大(比如数百个),预建所有连接可能占用过多内存,此时可以结合连接缓存策略(比如按需连接后保持10分钟,超时释放),但数量可控时预建是最优解。
内容的提问来源于stack exchange,提问作者Tow
相关产品推荐
相关产品推荐

