56 lines
2.4 KiB
Markdown
56 lines
2.4 KiB
Markdown
# 动态数据源
|
||
|
||
系统支持在服务启动**之后**再配置数据库,并可在 SQLite 与 MySQL 之间运行时切换,无需启动前准备。
|
||
|
||
## 设计目标
|
||
|
||
- 未配置数据库时应用仍能正常启动,前端引导进入初始化页面。
|
||
- 支持 SQLite(本地单文件)与 MySQL 两种数据库。
|
||
- 保存配置后立即生效并自动建表,无需手动执行 SQL。
|
||
|
||
## 核心组件
|
||
|
||
| 组件 | 职责 |
|
||
|---|---|
|
||
| `DynamicDataSource` | 继承 `AbstractRoutingDataSource`,维护目标数据源映射,切换时重建解析缓存并关闭旧连接池 |
|
||
| `DataSourceContextHolder` | 保存当前数据源 key 与类型;未配置时使用 `UNCONFIGURED` 占位 |
|
||
| `UnconfiguredDataSource` | 占位数据源,任何取连接操作抛「数据库未配置」(业务码 5031) |
|
||
| `DatabaseConfig` / `DatabaseConfigStore` | 配置模型与持久化(`config/database.json`) |
|
||
| `SchemaInitializer` | 按类型执行 `init.sql`(MySQL)或 `schema-sqlite.sql`(SQLite),幂等建表 |
|
||
| `SchemaMigrator` | 建表后的幂等结构迁移(如列重命名),启动与切换数据源时执行 |
|
||
| `DatabaseBootstrap` | 应用启动后加载配置并初始化 |
|
||
|
||
`FinanceApplication` 刻意排除了 `DataSourceAutoConfiguration`,以便「零配置也能启动」。
|
||
|
||
## 配置来源与顺序
|
||
|
||
1. 优先读取本地 `config/database.json`。
|
||
2. 若无本地配置但存在环境变量 `DB_URL` / `DB_USERNAME` / `DB_PASSWORD`,则作为首次配置并保存。
|
||
|
||
保存流程为:**创建并测试新数据源 → 建表 → 结构迁移 → 先落盘再切换**,确保切换失败时可回退。
|
||
|
||
## 连接池策略
|
||
|
||
- SQLite:连接池固定为 1,避免文件锁冲突。
|
||
- MySQL:最大 10、最小 2。
|
||
|
||
MySQL 的 JDBC URL 会自动附带 UTF-8、关闭 SSL、`Asia/Shanghai` 时区与 `createDatabaseIfNotExist=true`。
|
||
|
||
## 跨库方言适配
|
||
|
||
统计模块依据 `DataSourceContextHolder.getType()` 选择时间分组函数:
|
||
|
||
- MySQL:`DATE_FORMAT` / `QUARTER`
|
||
- SQLite:`strftime`
|
||
|
||
## 切换行为
|
||
|
||
登录后可在「系统设置 → 数据库配置」随时切换数据库。切换后原数据库的数据保留,**不做自动迁移**。
|
||
|
||
切换成功后会清空进程内的用户偏好缓存(见[整体架构](/dev/architecture)),避免读到旧库的数据。
|
||
|
||
## 相关文档
|
||
|
||
- [快速开始](/guide/getting-started)
|
||
- [数据模型](/dev/data-model)
|