Nestjs框架: 数据库多租户模式与动态模块初探

Nestjs框架: 多租户与多数据库的架构设计与实现 本文介绍了在NestJS项目中实现多数据库对接的方案,重点解决多租户架构下的数据隔离与灵活切换需求。通过抽象层统一接口,结合TypeORM、Prisma和Mongoose三种ORM库,支持MySQL、PostgreSQL和MongoDB等多种数据库类型。方案采用外观模式+抽象工厂模式+策略模式,通过DatabaseModule集中管理数据库连接,根据租户ID动态切换不同数据库配置。文章详细阐述了环境变量设计、目录结构和模块实现,为复杂业务场景下的多数据库管理提供了可行方案。 阅读详情

概述

  • TypeORM 可以通过 TypeORM 中的 forRootAsync 方法读取点位文件中的配置信息,随后它会自动加载驱动,以便与各类数据库进行对接
  • Prisma 部分依托于 PrismaClient,无需手动安装数据库驱动。我们直接扩展 PrismaClient 就能得到一个 PrismaService,进而实现对数据库的读写操作
  • 至于 Mongoose 与 上面两个类似
  • 我们的目标是让项目既能与单库对接,也能应对多库场景

关于多租户

  • 以用户进入系统为例,NestJS 会读取当前用户的租户信息
  • 每个用户都携带不同的标签,不同的标签用于区分读取不同的数据库
  • 根据用户标签读取不同数据库的配置信息从而获取不同数据库的实例来操作对应的数据库
  • 这时候,就需要依赖 动态模块 (Dynamic Module)
    • 动态模块提供一种API, 将一个模块导入到另外一个模块
    • 并且定义该模块属性的时候可以 影响到 它的属性和行为
    • 动态模块 可以让人非常方便的自定义模块,并且注册和配置它
    • 在注册模块的过程中,对其配置,传入参数,注册逻辑进行定制
    • 这是分层化编程的思想, AOP 编程
  • 单库读取相对简单,而通用框架通常会涵盖单库功能
  • 所以,我们着重针对多库场景进行数据库设计
  • 要把程序封装起来,通过依赖注入的方式读取配置来定义 url

Prisma 的多租户系统集成

  • 之前,我们集成Prisma的时候,是用了一套配置,也就是一个数据库的配置
  • 在相关service里面,如下
    import {
         
          Injectable, OnModuleInit } from '@nestjs/common';
    import {
         
          PrismaClient } from '@prisma/client';
    
    @Injectable()
    export class PrismaService extends PrismaClient implements OnModuleInit {
         
         
      async onModuleInit() {
         
         
        await this.$connect();
      }
    }
    
    • 上面,PrismaService 继承了 PrismaClient 类,并实现了 OnModuleInit 这个生命周期方法
    • 该方法内部会调用 Prisma 的 $connect 方法来连接对应的数据库
  • 如果应用场景需要通过 Prisma 操作多个数据库,就不能使用同一套配置
  • 因为不同用户可能属于不同租户,所以要以租户为单元,让不同用户读取不同的数据库配置
  • 这就引出了一个问题:Prisma 如何动态接收配置?
  • 参考: accessing-environment-variables-from-the-schema
  • 就是用程序的方式,动态的写这个 url, 也就是把 datasouce url 拆分成不同字段,这样的目的就是把 url 拆分成 host, user, password 等字段分开管理
  • 生成不同的 PrismaClient 存放到 map 中, 后续,当不同的 用户 过来之后,通过 map 定位到 不同的 PrismaClient 从而操作不同数据库
  • 普通的写法只能让 Prisma 读取配置文件中的一个数据库,如果要实现动态配置,需要参考 之前 TypeOrmModule.forRootAsync 的方法 传递给 prisma.module.ts,并通过依赖注入的方式将 ConfigService 注入其中
  • 接收到数据后,我们需要将其拼接成 Prisma 要求的结构,这就需要了解 connectionURLs 的格式,通常前面是数据库类型、用户密码、主机和端口,后面可能还有查询参数,参考:connection-urls

如何实现动态模块

  • 我们知道 TypeOrmModule.forRoot 和 TypeOrmModule.forRootAsync 都是 Dynamic modules 即动态模块
  • 我们探索其源码,如下
    import {
         
          DynamicModule } from '@nestjs/common';
    import {
         
          DataSource, DataSourceOptions } from 'typeorm';
    import {
         
          EntityClassOrSchema } from './interfaces/entity-class-or-schema.type';
    import {
         
          TypeOrmModuleAsyncOptions, TypeOrmModuleOptions } from './interfaces/typeorm-options.interface';
    export declare class TypeOrmModule {
         
         
        static forRoot(options?: TypeOrmModuleOptions): DynamicModule;
        static forFeature(entities?: EntityClassOrSchema[], dataSource?: DataSource | DataSourceOptions | string): DynamicModule;
        static forRootAsync(options: TypeOrmModuleAsyncOptions): DynamicModule;
    }
    <
NestJS模块化架构:从基础到动态模块的实战演进 本文深入探讨了NestJS模块化架构的演进过程,从基础模块到动态模块的实战应用。通过电商项目案例,展示了如何通过模块化设计提升代码维护效率和系统性能,包括共享模块、全局模块和动态模块的高级用法。文章还提供了模块化架构的演进策略和常见问题解决方案,帮助开发者更好地利用NestJS构建可扩展的后端服务。 阅读详情

相关推荐

Nestjs框架: 基于TypeORM的多租户功能集成和优化

本文介绍了如何通过Docker Compose配置多租户数据库环境(包含2个MySQL和1个PostgreSQL实例),并集成到NestJS项目中。首先展示了docker-compose配置文件,详细说明了三个数据库服务的端口映射、数据卷挂载等关键配置。接着通过Adminer工具验证数据库连接并创建测试库。然后重点讲解了TypeORM CLI的配置方法,包括环境变量设置、ORM配置文件编写以及数据库同步脚本的创建。最后提供了针对不同数据库的.env配置示例,并说明了如何执行TypeORM同步命令来初始化数据

Wang的专栏 1717

nestjs-tenancy:nestjs 的多租户方法 - 目前仅支持 mongodb with mongoose

nestjs-租户 一个简单易用的 NestJs 和 Mongoose 多租户模块 描述 用于多租户模块。 安装 $ npm i --save @needle-innovision/nestjs-tenancy 基本用法 app.module.ts import { Module } from "@nestjs/common" ; import { TenancyModule } from "@needle-innovision/nestjs-tenancy" ; import { CatsModule } from "./cat.module.ts" ; @ Module ( { imports : [ TenancyModule . forRoot ( { tenantIdentifier : 'X-TENANT-ID' , option

全栈Next.js应用平台:一个支持多租户和自定义域的全栈Next.js应用程序的开发平台

一个支持多租户和自定义域的全栈Next.js应用程序的开发平台。它基于Next.js应用路由器和Vercel域API,提供了强大的功能和灵活性,让开发人员可以构建具有多租户和自定义域的全栈应用程序。

冗余位技术在SAR ADC中的动态误差恢复机制解析

本文深入解析了冗余位技术在SAR ADC中的动态误差恢复机制,详细介绍了其基本概念、动态误差产生原因及冗余位的容错空间设计、时序松弛策略和数字校正算法。通过实际电路设计案例和数学建模,展示了冗余位技术如何显著提升ADC的精度和能效比,同时探讨了未来发展方向。

weixin_28335283的博客 977

合泰单片机HT32之keil5开发环境搭建(一)

1. 前言 这两天在准备合泰杯,但是总是感觉无从下手,因为合泰单片机的资料教程什么的非常少,不像stm32那样。而且听说要用合泰单片机的专用IDE,感觉当场被劝退了。后来经过查找资料,发现合泰单片机也有keil5的支持包,也就是说可以从库函数进行开发,不用从寄存器进行开发,但我找了好久,并没有找到教程,后来实在没办法,打算自己动手搭建环境,经过了大概两天的挣扎后,终于成功地搭建好了环境,也成功地点...

weixin_44713763的博客 8671

基于MATLAB的基本数字调制解调系统的设计

基于MATLAB的基本数字调制解调系统的设计一、摘要现代通信系统要求通信距离远、通信容量大、传输质量好,作为其关键技术之一的调制解调技术一直是人们研究的一个重要方向。本文以MATLAB为软件平台,充分利用其提供的通信工具箱和信号处理工具箱中的模块,对数字调制解调系统进行Simulink设计仿真,并且进行误差分析。调制与解调是通信系统中十分重要的一个环节,针对不同的信道环境选择不同的调制与解调方式可...

m0_55395440的博客 5550

从2804云台电机到桌面机械臂:一个STM32/GD32玩家的FOC驱动踩坑全记录

本文详细记录了从2804云台电机到桌面机械臂的FOC驱动开发历程,涵盖了硬件选型、驱动方案优化、软件调试等关键环节。特别分享了L6234P驱动芯片的发热问题、AS5600编码器的I2C通信陷阱以及PID调参的实战经验,为DIY爱好者提供了宝贵的参考。

weixin_26897585的博客 483

《Python星球日记》 第73天:情感分析与主题建模

《Python星球日记》 第73天:情感分析与主题建模,今天我们将探索两个自然语言处理领域的重要技术:情感分析和主题建模。这两项技术在社交媒体分析、用户反馈处理、市场研究等多个领域有着广泛应用。

Code_流苏:在代码中寻诗意,在实践中觅真知 919

MATLAB - 机械臂手眼标定(眼在手内) - 估计安装在机器人上的移动相机的姿态

执行手眼校准有助于操作配备末端执行器(简称 “手”)的机械臂,该末端执行器依赖于摄像头提供的视觉数据。一旦完成了眼在手外的校准,机械臂就能准确地移动到摄像头识别的特定像素位置。这种能力是执行精确拾放任务(如分类、堆垛和分拣)的基础,即使在摄像机的确切位置和方向未知的情况下也是如此。机器人-摄像机系统有两种构型:眼在手内和眼在手外。在眼在手内构型中,摄像头直接安装在机器人手臂的末端执行器上。相反,在眼在手的构型中,摄像头固定在一个静止的物体上,机器人手臂在其视野内。

机器人控制与仿真应用 3355

用 SemanticObject 把字段变成可点击链接:Fiori Elements Navigation Using a Link 的工程化实践

SAP Fiori elements 通过 Common.SemanticObject 注解可将字段转为可点击链接,实现应用间跳转。当源字段名与目标属性名不一致时,需使用 Common.SemanticObjectMapping 进行映射。该功能依赖 Fiori Launchpad 的目标映射配置,确保正确解析 semantic object + action 并传递参数。常见误区包括未配置目标映射或字段映射错误,需逐一检查语义标注、intent 解析和参数传递链路。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 273

RK3588 部署 YOLO26-Pose 人体姿态检测:Windows Docker 环境全流程

YOLO26-Pose 在 RK3588 上的部署流程是 PC 端 ONNX 导出 → RKNN 转换(INT8 量化)→ 板端推理。INT8 量化后 YOLO26s-Pose 约 35ms,YOLO26n-Pose 约 15ms,可以覆盖实时姿态检测的需求。后处理是 Python 实现的常见瓶颈——如果帧率不达标,先用 npy 保存模型输出在 PC 上验证解析逻辑的正确性,确认无误后再迁移到 C++ 实现。

m0_64661770的博客 545

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: Nestjs框架: 集成 TypeORM 和 Mongoose
下一篇: Nestjs框架: 数据库架构设计与 NestJS 多 ORM 动态数据库应用与连接池的配置
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值