本文目录导读:
- Spring Boot + JPA/MyBatis(Java 生态最典型)
- AdonisJS + Lucid ORM (Node.js 全栈框架)
- Django + ORM (Python 全栈框架)
- Next.js + Prisma (TypeScript 全栈)
- 通用设计原则与注意事项
- 总结:如何选择?
全栈框架中配置多数据库(多数据源)是常见的需求,比如读写分离、分库分表、或对接不同业务数据库,具体实现方式因框架和语言而异,但核心思路一致:配置多个数据源,并在需要时指定使用哪个数据源。
下面以几个主流全栈框架为例,说明如何配置多数据库。
Spring Boot + JPA/MyBatis(Java 生态最典型)
这是最经典的全栈后端框架,Spring Boot 对多数据源支持很好,通常通过 @Primary 和 @Qualifier 或分包策略实现。
核心步骤(2个数据源:Primary + Secondary):
-
配置
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 -
创建数据源配置类(关键):
@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(); } } -
分别配置 EntityManager/ SqlSessionFactory(不同包路径):
- 将操作
db1的实体类放在com.example.db1.entity,操作db2的放在com.example.db2.entity。 - 为每个数据源创建对应的
LocalContainerEntityManagerFactoryBean(JPA)或SqlSessionFactoryBean(MyBatis),并扫描对应包。
- 将操作
-
使用:
- 在 Service 层,通过
@Autowired+@Qualifier("primaryJdbcTemplate")使用对应数据源的 JdbcTemplate/Repository。 - 或使用开源库
@DS("secondary")(如 baomidou 的 MyBatis-Plus 多数据源插件)。
- 在 Service 层,通过
优点:稳定、成熟、社区支持强
缺点:配置稍繁琐,需要分包管理(除非使用动态数据源路由)
AdonisJS + Lucid ORM (Node.js 全栈框架)
AdonisJS 是 Node.js 领域功能完善的全栈框架,ORM 是 Lucid(基于 Knex.js)。
配置方法:
-
编辑
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' } } } }; -
在查询时指定连接:
// 模型使用默认连接 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 原生支持多数据库。
配置方法:
-
编辑
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', } } -
数据库路由(重点): 创建
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 -
在
settings.py中添加路由:DATABASE_ROUTERS = ['path.to.db_routers.AnalyticsRouter']
-
手动使用(无需路由时):
# 直接在查询时指定 using obj = MyModel.objects.using('analytics').get(id=1)
优点:Django 官方设计,高度集成,路由逻辑灵活
缺点:需要学习路由机制,跨库关联查询复杂
Next.js + Prisma (TypeScript 全栈)
Next.js 偏向前端全栈,但配合 Prisma 也能实现多数据库,Prisma 原生不直接支持同一应用内同时连接多个不同数据库(截至 2025 年),需要一些变通:
方案:多个 Prisma 客户端实例
-
创建两个 Schema 文件:
prisma/schema1.prisma(MySQL)prisma/schema2.prisma(PostgreSQL)
-
配置两个数据源(每个 schema 指定自己的数据源):
// schema1.prisma datasource db1 { provider = "mysql" url = env("DATABASE_URL_MYSQL") } // schema2.prisma datasource db2 { provider = "postgresql" url = env("DATABASE_URL_POSTGRES") } -
生成两个客户端:
npx prisma generate --schema=prisma/schema1.prisma npx prisma generate --schema=prisma/schema2.prisma
-
在代码中分别实例化:
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;事务跨库需要手动处理
通用设计原则与注意事项
-
事务边界:
- 多数据库 不支持全局分布式事务(除非引入 XA 或 Saga 模式,如 Seata)。
- 通常业务逻辑中,尽量在单个请求内只操作一个数据源,避免跨库强一致性事务。
-
查询性能:
- 跨库关联查询(JOIN)不可能,必须在应用层做多次查询再合并(会引发 N+1 问题)。
- 建议通过冗余字段或聚合服务(如 ES)缓解。
-
管理成本:
- 尽量使用 动态数据源路由(如根据
@DS注解或ThreadLocal),减少手工切换的错误。 - 数据库连接池需独立配置,避免互相影响。
- 尽量使用 动态数据源路由(如根据
-
迁移与 Schema 管理:
- 每个数据库的迁移脚本独立存放。
- 注意
ignore_migrations(如 Django)或分别执行 Prisma migrate。
-
测试:
- 单元测试时,尽量使用内存数据库(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 更高效。
- 永远不要为了“多数据库”而多数据库,尽量让一个核心业务只依赖一个主数据库,其他作为辅助(日志、分析、缓存)。
标签: 多数据库配置