跳到主要内容

ZenWeb Tenant module

ZenWeb

多租户多数据库支持

安装

yarn add @zenweb/tenant

配置

编辑项目入口代码 src/index.ts

src/index.ts
import { create } from 'zenweb';
import modTenant, { Tenant } from '@zenweb/tenant';

export const app = create();

/**
* 租户配置信息(代码演示)
*/
const tenantsConfig: { [id: string]: Tenant } = {
'a.demo.com': {
server: 'S1',
database: 'db_1',
},
'b.demo.com': {
server: 'S2',
database: 'db_2',
},
};

app.setup(modTenant({
tenantGetter: ctx => {
const tenant = tenantsConfig[ctx.host];
if (!tenant) {
throw new Error('Tennat not exists: ' + ctx.host);
}
return tenant;
},
pools: {
S1: { // 数据库服务器名称
MASTER: { // 主库
host: '127.0.0.1',
port: 3306,
user: 'root',
password: '123456',
charset: 'utf8mb4',
timezone: '+08:00',
connectionLimit: 100,
},
// 从库配置
// SLAVES: []
},
S2: {
MASTER: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: '',
charset: 'utf8mb4',
timezone: '+08:00',
connectionLimit: 100,
},
},
},
}));

代码中调用

使用 MySQL 原生查询

src/controller/test.ts
import { mapping, Context } from 'zenweb';

export class TestController {
@mappping()
dbtest(ctx: Context) {
// 默认使用主库 MASTER
await ctx.mysql.query("SELECT 1+1");
// 指定使用主库
await ctx.mysql.of("MASTER").query("SELECT 1+1");
// 指定使用从库 - 对于没有配置从库的会自动切换成主库 MASTER
await ctx.mysql.of("SLAVE*").query("SELECT 1+1");
}
}

[可选] 集成 ZenORM

安装

# 生产依赖
yarn add zenorm

# 开发依赖
yarn add --dev @zenorm/generate @zenorm/generate-mysql

配置

package.jsonscripts 中增加如下代码,用于执行 dbgen 命令

package.json
{
"scripts": {
"dbgen": "zenorm-generate .dbgen.js"
}
}

创建文件 .dbgen.js 用于生成数据库结构代码时连接到指定数据库

提示:运行时并不使用此配置

.dbgen.js
/** @type {import("@zenorm/generate").GenerateConfig} */
module.exports = {
host: "localhost",
port: 3306,
user: "root",
password: "",
database: "zenorm_test",
outputDir: "./model",
bindQuery: true,
};

生成数据库结构代码

运行命令开始生成数据库结构代码

yarn dbgen

配置项目代码

编辑项目入口代码 src/index.ts

src/index.ts
// 导入 ORM 生成的 bindQuery 方法
import { bindQuery } from './model';

// 修改配置好的 modTenant
// 集成 ZenORM
app.setup(modTenant({
// ... modTenant 配置
bindQuery, // ORM 查询绑定
});

代码中调用 ORM 模型

src/controller/test.ts
import { mapping } from 'zenweb';
import { User } from '../model';

export class TestController {
@mapping()
orm() {
return User.find({ id: 1 }).get();
}
}