Files
ledgerly-docs/dev/database.md
T
rosercode b979c6e498 refactor: 文档站品牌改名为汇账 Ledgerly,站点与脚本标识统一为 ledgerly
- 站点标题、首页与文档正文品牌名由「收支管理系统」改为「汇账 Ledgerly」
- package.json 包名改为 ledgerly-docs
- 维护脚本环境变量由 FINANCE_* 改为 LEDGERLY_*,测试库路径与示例同步
- 项目结构、构建部署、开发环境等文档中的目录名与 jar 名改为 ledgerly
- 保留在线体验域名与 OSS 截图前缀不变
2026-09-23 17:33:59 +08:00

56 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 动态数据源
系统支持在服务启动**之后**再配置数据库,并可在 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` | 应用启动后加载配置并初始化 |
`LedgerlyApplication` 刻意排除了 `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)