全栈框架多数据库配置?

访客 全栈框架 2

本文目录导读:

  1. Spring Boot + JPA/MyBatis(Java 生态最典型)
  2. AdonisJS + Lucid ORM (Node.js 全栈框架)
  3. Django + ORM (Python 全栈框架)
  4. Next.js + Prisma (TypeScript 全栈)
  5. 通用设计原则与注意事项
  6. 总结:如何选择?

全栈框架中配置多数据库(多数据源)是常见的需求,比如读写分离、分库分表、或对接不同业务数据库,具体实现方式因框架和语言而异,但核心思路一致:配置多个数据源,并在需要时指定使用哪个数据源

下面以几个主流全栈框架为例,说明如何配置多数据库。


Spring Boot + JPA/MyBatis(Java 生态最典型)

这是最经典的全栈后端框架,Spring Boot 对多数据源支持很好,通常通过 @Primary@Qualifier 或分包策略实现。

核心步骤(2个数据源:Primary + Secondary):

  1. 配置 application.yml

    spring:
      datasource:
        primary:
          jdbc-url: jdbc:mysql://localhost:3306/db1
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
        secondary:
          jdbc-url: jdbc:postgresql://localhost:5432/db2
          username: postgres
          password: postgres
          driver-class-name: org.postgresql.Driver
  2. 创建数据源配置类(关键):

    @Configuration
    public class DataSourceConfig {
        @Primary
        @Bean(name = "primaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.primary")
        public DataSource primaryDataSource() {
            return DataSourceBuilder.create().build();
        }
        @Bean(name = "secondaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    }
  3. 分别配置 EntityManager/ SqlSessionFactory(不同包路径):

    • 将操作 db1 的实体类放在 com.example.db1.entity,操作 db2 的放在 com.example.db2.entity
    • 为每个数据源创建对应的 LocalContainerEntityManagerFactoryBean(JPA)或 SqlSessionFactoryBean(MyBatis),并扫描对应包。
  4. 使用

    • 在 Service 层,通过 @Autowired + @Qualifier("primaryJdbcTemplate") 使用对应数据源的 JdbcTemplate/Repository。
    • 或使用开源库 @DS("secondary")(如 baomidou 的 MyBatis-Plus 多数据源插件)。

优点:稳定、成熟、社区支持强
缺点:配置稍繁琐,需要分包管理(除非使用动态数据源路由)


AdonisJS + Lucid ORM (Node.js 全栈框架)

AdonisJS 是 Node.js 领域功能完善的全栈框架,ORM 是 Lucid(基于 Knex.js)。

配置方法:

  1. 编辑 config/database.js

    const DatabaseConfig = {
      connection: 'mysql', // 默认连接
      connections: {
        mysql: {
          client: 'mysql2',
          connection: {
            host: '127.0.0.1',
            port: 3306,
            user: 'root',
            password: '',
            database: 'db1'
          }
        },
        postgres: {
          client: 'pg',
          connection: {
            host: '127.0.0.1',
            port: 5432,
            user: 'postgres',
            password: '',
            database: 'db2'
          }
        }
      }
    };
  2. 在查询时指定连接

    // 模型使用默认连接
    const users = await User.all()
    // 指定使用 postgres 连接
    const reports = await Database.connection('postgres')
      .table('reports')
      .where('status', 'active')
    // 模型层面指定
    class Report extends Model {
      static get connection() {
        return 'postgres'
      }
    }

优点:配置非常简洁,项目结构和概念清晰
缺点:社区相对 Java/Spring 生态小,高级分布式场景支持需自己扩展


Django + ORM (Python 全栈框架)

Django 的 ORM 原生支持多数据库。

配置方法:

  1. 编辑 settings.py

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'db1',
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': 'localhost',
            'PORT': '3306',
        },
        'analytics': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'db2',
            'USER': 'postgres',
            'PASSWORD': 'postgres',
            'HOST': 'localhost',
            'PORT': '5432',
        }
    }
  2. 数据库路由(重点): 创建 db_routers.py 文件,定义读写规则,哪些 Model 使用哪个库:

    class AnalyticsRouter:
        def db_for_read(self, model, **hints):
            if model._meta.app_label == 'analytics_app':
                return 'analytics'
            return None
        def db_for_write(self, model, **hints):
            if model._meta.app_label == 'analytics_app':
                return 'analytics'
            return None
        def allow_migrate(self, db, app_label, model_name=None, **hints):
            if app_label == 'analytics_app':
                return db == 'analytics'
            return None
  3. settings.py 中添加路由

    DATABASE_ROUTERS = ['path.to.db_routers.AnalyticsRouter']
  4. 手动使用(无需路由时):

    # 直接在查询时指定 using
    obj = MyModel.objects.using('analytics').get(id=1)

优点:Django 官方设计,高度集成,路由逻辑灵活
缺点:需要学习路由机制,跨库关联查询复杂


Next.js + Prisma (TypeScript 全栈)

Next.js 偏向前端全栈,但配合 Prisma 也能实现多数据库,Prisma 原生不直接支持同一应用内同时连接多个不同数据库(截至 2025 年),需要一些变通:

方案:多个 Prisma 客户端实例

  1. 创建两个 Schema 文件

    • prisma/schema1.prisma (MySQL)
    • prisma/schema2.prisma (PostgreSQL)
  2. 配置两个数据源(每个 schema 指定自己的数据源):

    // schema1.prisma
    datasource db1 {
      provider = "mysql"
      url      = env("DATABASE_URL_MYSQL")
    }
    // schema2.prisma
    datasource db2 {
      provider = "postgresql"
      url      = env("DATABASE_URL_POSTGRES")
    }
  3. 生成两个客户端

    npx prisma generate --schema=prisma/schema1.prisma
    npx prisma generate --schema=prisma/schema2.prisma
  4. 在代码中分别实例化

    import { PrismaClient as PrismaClient1 } from '@prisma/client1'
    import { PrismaClient as PrismaClient2 } from '@prisma/client2'
    export const prisma1 = new PrismaClient1()
    export const prisma2 = new PrismaClient2()
    // 使用时
    const users = await prisma1.user.findMany()
    const logs = await prisma2.log.findMany()

优点:TypeScript 类型安全,适合前端全栈开发者
缺点:配置不够优雅,需要维护两份 schema;事务跨库需要手动处理


通用设计原则与注意事项

  1. 事务边界

    • 多数据库 不支持全局分布式事务(除非引入 XA 或 Saga 模式,如 Seata)。
    • 通常业务逻辑中,尽量在单个请求内只操作一个数据源,避免跨库强一致性事务。
  2. 查询性能

    • 跨库关联查询(JOIN)不可能,必须在应用层做多次查询再合并(会引发 N+1 问题)。
    • 建议通过冗余字段或聚合服务(如 ES)缓解。
  3. 管理成本

    • 尽量使用 动态数据源路由(如根据 @DS 注解或 ThreadLocal),减少手工切换的错误。
    • 数据库连接池需独立配置,避免互相影响。
  4. 迁移与 Schema 管理

    • 每个数据库的迁移脚本独立存放。
    • 注意 ignore_migrations(如 Django)或分别执行 Prisma migrate。
  5. 测试

    • 单元测试时,尽量使用内存数据库(H2 / SQLite)模拟多数据源。
    • 集成测试需要启动真实数据库容器(Testcontainers)。

如何选择?

框架 推荐度 适用场景 学习曲线
Spring Boot (Java) 企业级、分布式、大规模项目 中等
AdonisJS (Node) 快速原型、Node.js 全栈、中小项目 较低
Django (Python) 数据密集型、内容管理、REST API 中等
Next.js + Prisma (TS) 前端驱动、Serverless、轻量应用 较低(但多库配置麻烦)

核心建议

  • 如果项目需要处理复杂业务逻辑、强一致性、跨库事务,首选 Spring Boot + 动态数据源 + Seata。
  • 如果项目快速迭代、前端友好、JAMStack 风格,Next.js + Prisma 或 AdonisJS 更高效。
  • 永远不要为了“多数据库”而多数据库,尽量让一个核心业务只依赖一个主数据库,其他作为辅助(日志、分析、缓存)。

标签: 多数据库配置

抱歉,评论功能暂时关闭!