背景
在开发运维平台时,需要支持多分支环境,每个分支连接不同的数据库。为了实现数据库的动态切换,对 egg-mongoose 进行了多数据库配置。由于网上相关资料较少,特此记录实现方案。
实现步骤
1. 配置多数据库连接
在 config.default.js 中配置多个数据库连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| config.mongoose = { clients: { local: { url: 'mongodb://xxx:xxx@xxx:/xxx-s?authSource=admin', options: { }, }, master: { url: 'mongodb://xxxx:xxx@xxxxx:/xxxx?authSource=admin&authMechanism=SCRAM-SHA-1', options: { } }, }, }
|
2. Model 定义
需要为每个数据库连接创建对应的 Model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { Application } from "egg";
module.exports = (app: Application) => { const mongoose = app.mongoose; const Schema = mongoose.Schema; const GameUserSchema = new Schema({}); const conn = app.mongooseDB.get('v'); const GameUserModel = conn.model('nnnn', GameUserSchema); return GameUserModel; };
|
3. 统一的 Model 获取方法
在 Service 层实现统一的 Model 获取方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| getModel(dbName: string) { let config = NATENDPOINT.find(nat => nat.port == this.ctx.natServer); if (!config) { throw new Error('内部异常'); } let mongooseConfig = config.mongoose.find((_mongo) => _mongo.dbName == dbName); if (!mongooseConfig) { throw new Error('内部异常'); } return this.ctx.model[mongooseConfig.fileName]; }
|
自动生成 Model 文件
为了提高开发效率,实现了自动生成 Model 文件的脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import { dddd } from "./app/utils/constants"; const fs = require("fs"); const path = require("path");
for (let server of dddd) { if (!server.mongodb) continue; for (let mongooseConfig of server.mongoose) { let savePath = path.join(__dirname, `./app/model/${mongooseConfig.fileName}.ts`); let inputData = `// Code AutoGenerate. DO NOT EDIT.\n import { Application } from "egg";\n module.exports = (app: Application) => { const mongoose = app.mongoose; const Schema = mongoose.Schema; const ${mongooseConfig.schemaName}Schema = new Schema({}); const conn = app.mongooseDB.get('${server.mongodb}'); const ${mongooseConfig.schemaName}Model = conn.model('${mongooseConfig.dbName}', ${mongooseConfig.schemaName}Schema); return ${mongooseConfig.schemaName}Model; };`; fs.writeFile(savePath, inputData, (err) => { if (err) throw err; console.log("autoGenerate modal success"); }); } }
|
注意事项
- Schema 定义虽然可以为空,但建议根据实际需求定义字段
- Model 命名需要注意,egg 会自动处理大小写
- 建议将常用数据同步到本地数据库,添加索引提升查询性能
总结
通过合理配置 egg-mongoose 多数据库连接,可以实现灵活的数据库切换。配合自动生成 Model 文件的脚本,可以显著提升开发效率。