288 lines
11 KiB
Markdown
288 lines
11 KiB
Markdown
# 数据库客户端后端架构设计文档
|
||
|
||
**文档版本**:v2.0
|
||
**维护者**:JueChen
|
||
**更新日期**:2025-01-28
|
||
**源码路径**:`go-desk/`
|
||
|
||
---
|
||
|
||
## 一、整体架构概览
|
||
|
||
### 1.1 分层架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 接口层(API Layer) │
|
||
│ ┌──────────────────────────────────────────────────────┐ │
|
||
│ │ app.go (Wails App 接口) │ │
|
||
│ └──────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 服务层(Service Layer) │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ConnectionSvc │ │ SqlExecSvc │ │ ResourceSvc │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
│ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ TabSvc │ │ BookmarkSvc │ │
|
||
│ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 数据访问层(Data Access Layer) │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ Storage │ │ DBClient │ │ Models │ │
|
||
│ │ (SQLite) │ │ (Pool) │ │ │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 基础设施层(Infrastructure Layer) │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ Crypto │ │ Filesystem │ │ System │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 1.2 架构设计原则
|
||
|
||
1. **单一职责原则**:每个服务只负责一个业务领域
|
||
2. **依赖倒置原则**:接口定义在服务层,实现在数据访问层
|
||
3. **关注点分离**:接口、业务逻辑、数据访问分离
|
||
4. **可测试性**:通过接口抽象,便于单元测试
|
||
5. **可扩展性**:新增功能只需添加新的服务
|
||
|
||
---
|
||
|
||
## 二、目录结构
|
||
|
||
```
|
||
go-desk/
|
||
├── main.go # 应用入口
|
||
├── app.go # Wails App 接口(精简后)
|
||
├── internal/
|
||
│ ├── api/ # API 接口层(新增)
|
||
│ │ ├── connection_api.go # 连接管理接口
|
||
│ │ ├── sql_api.go # SQL执行接口
|
||
│ │ ├── resource_api.go # 资源管理接口
|
||
│ │ └── tab_api.go # 标签页接口
|
||
│ │
|
||
│ ├── service/ # 服务层(新增)
|
||
│ │ ├── connection_service.go # 连接管理服务
|
||
│ │ ├── sql_exec_service.go # SQL执行服务
|
||
│ │ ├── resource_service.go # 资源管理服务
|
||
│ │ └── tab_service.go # 标签页服务
|
||
│ │
|
||
│ ├── storage/ # 数据访问层
|
||
│ │ ├── sqlite.go # SQLite 初始化
|
||
│ │ ├── models/ # 数据模型
|
||
│ │ │ ├── connection.go
|
||
│ │ │ ├── sql_tab.go
|
||
│ │ │ ├── bookmark.go
|
||
│ │ │ └── template.go
|
||
│ │ └── repository/ # 数据仓库(新增)
|
||
│ │ ├── connection_repo.go
|
||
│ │ ├── tab_repo.go
|
||
│ │ ├── bookmark_repo.go
|
||
│ │ └── template_repo.go
|
||
│ │
|
||
│ ├── dbclient/ # 数据库客户端
|
||
│ │ ├── pool.go # 连接池管理
|
||
│ │ ├── mysql.go # MySQL 客户端
|
||
│ │ ├── redis.go # Redis 客户端
|
||
│ │ └── mongo.go # MongoDB 客户端
|
||
│ │
|
||
│ ├── crypto/ # 加密工具
|
||
│ ├── filesystem/ # 文件系统
|
||
│ └── system/ # 系统信息
|
||
```
|
||
|
||
---
|
||
|
||
## 三、服务层设计
|
||
|
||
### 3.1 ConnectionService
|
||
|
||
**职责**:管理数据库连接配置
|
||
|
||
**方法**:
|
||
- `SaveConnection(conn *models.DbConnection) error`
|
||
- `ListConnections() ([]models.DbConnection, error)`
|
||
- `GetConnection(id uint) (*models.DbConnection, error)`
|
||
- `DeleteConnection(id uint) error`
|
||
- `TestConnection(conn *models.DbConnection) error`
|
||
|
||
**依赖**:
|
||
- `ConnectionRepository`:数据访问接口
|
||
|
||
### 3.2 SqlExecService
|
||
|
||
**职责**:执行 SQL 语句
|
||
|
||
**方法**:
|
||
- `ExecuteSQL(connectionId uint, sqlStr string, database string) (*SqlResult, error)`
|
||
- `GetDatabases(connectionId uint) ([]string, error)`
|
||
- `GetTables(connectionId uint, database string) ([]string, error)`
|
||
|
||
**依赖**:
|
||
- `ConnectionService`:获取连接配置
|
||
- `ConnectionPool`:获取数据库客户端
|
||
|
||
### 3.3 ResourceService
|
||
|
||
**职责**:管理书签和模板
|
||
|
||
**方法**:
|
||
- `SaveBookmark(bookmark *models.Bookmark) error`
|
||
- `ListBookmarks(connectionId uint) ([]models.Bookmark, error)`
|
||
- `DeleteBookmark(id uint) error`
|
||
- `SaveTemplate(template *models.Template) error`
|
||
- `ListTemplates() ([]models.Template, error)`
|
||
- `DeleteTemplate(id uint) error`
|
||
|
||
**依赖**:
|
||
- `BookmarkRepository`:书签数据访问
|
||
- `TemplateRepository`:模板数据访问
|
||
|
||
### 3.4 TabService
|
||
|
||
**职责**:管理 SQL 标签页
|
||
|
||
**方法**:
|
||
- `SaveTabs(tabs []models.SqlTab) error`
|
||
- `ListTabs() ([]models.SqlTab, error)`
|
||
- `DeleteTab(id uint) error`
|
||
|
||
**依赖**:
|
||
- `TabRepository`:标签页数据访问
|
||
|
||
---
|
||
|
||
## 四、数据访问层设计
|
||
|
||
### 4.1 Repository 模式
|
||
|
||
使用 Repository 模式封装数据访问逻辑,提供统一的接口:
|
||
|
||
```go
|
||
type ConnectionRepository interface {
|
||
Save(conn *models.DbConnection) error
|
||
FindAll() ([]models.DbConnection, error)
|
||
FindByID(id uint) (*models.DbConnection, error)
|
||
Delete(id uint) error
|
||
}
|
||
```
|
||
|
||
### 4.2 实现方式
|
||
|
||
- `ConnectionRepository`:使用 GORM 实现
|
||
- `TabRepository`:使用 GORM 实现
|
||
- `BookmarkRepository`:使用 GORM 实现
|
||
- `TemplateRepository`:使用 GORM 实现
|
||
|
||
---
|
||
|
||
## 五、接口层设计
|
||
|
||
### 5.1 API 接口
|
||
|
||
将 `app.go` 中的方法按功能分组到不同的 API 文件中:
|
||
|
||
- `connection_api.go`:连接管理相关接口
|
||
- `sql_api.go`:SQL 执行相关接口
|
||
- `resource_api.go`:资源管理相关接口
|
||
- `tab_api.go`:标签页相关接口
|
||
|
||
### 5.2 App 结构体
|
||
|
||
`app.go` 只负责:
|
||
- 初始化服务
|
||
- 委托调用到对应的 API 接口
|
||
|
||
---
|
||
|
||
## 六、重构优势
|
||
|
||
### 6.1 代码组织
|
||
|
||
- **清晰的职责划分**:每个服务只负责一个业务领域
|
||
- **易于维护**:修改某个功能只需修改对应的服务
|
||
- **代码复用**:服务可以在多个 API 中复用
|
||
|
||
### 6.2 可测试性
|
||
|
||
- **独立测试**:每个服务可以独立测试
|
||
- **Mock 简单**:可以轻松 mock Repository
|
||
- **测试覆盖**:逻辑集中在服务层,测试更容易
|
||
|
||
### 6.3 可扩展性
|
||
|
||
- **新增功能**:只需添加新的服务和 API
|
||
- **功能组合**:可以组合多个服务实现复杂功能
|
||
- **向后兼容**:不影响现有接口
|
||
|
||
---
|
||
|
||
## 七、实施步骤
|
||
|
||
### 步骤1:创建目录结构 ✅
|
||
- [x] 创建 `internal/api/` 目录
|
||
- [x] 创建 `internal/service/` 目录
|
||
- [x] 创建 `internal/storage/repository/` 目录
|
||
|
||
### 步骤2:实现 Repository 层 ✅
|
||
- [x] 定义 Repository 接口
|
||
- [x] 实现 ConnectionRepository
|
||
- [x] 实现 TabRepository
|
||
- [x] 实现 BookmarkRepository
|
||
- [x] 实现 TemplateRepository
|
||
|
||
### 步骤3:实现 Service 层 ✅
|
||
- [x] 实现 ConnectionService
|
||
- [x] 实现 SqlExecService
|
||
- [x] 实现 ResourceService
|
||
- [x] 实现 TabService
|
||
|
||
### 步骤4:实现 API 层 ✅
|
||
- [x] 实现 connection_api.go
|
||
- [x] 实现 sql_api.go
|
||
- [x] 实现 resource_api.go
|
||
- [x] 实现 tab_api.go
|
||
|
||
### 步骤5:重构 app.go ✅
|
||
- [x] 连接管理方法迁移到 ConnectionAPI ✅
|
||
- [x] SQL执行方法迁移到 SqlAPI ✅
|
||
- [x] 书签管理方法迁移到 ResourceAPI ✅
|
||
- [x] 模板管理方法迁移到 ResourceAPI ✅
|
||
- [x] 标签页管理方法迁移到 TabAPI ✅
|
||
- [x] 表结构和索引查询方法迁移到 SqlAPI ✅
|
||
- [x] 删除重复代码(parseRedisCommand)✅
|
||
- [x] 简化 app.go,只保留初始化逻辑 ✅
|
||
|
||
### 步骤6:测试和验证 ⚠️
|
||
- [x] 功能测试(基本完成)
|
||
- [ ] 单元测试(待完成)
|
||
- [x] 代码审查(已完成)
|
||
|
||
---
|
||
|
||
## 八、后续优化方向
|
||
|
||
1. **依赖注入**:使用依赖注入框架管理服务依赖
|
||
2. **错误处理**:统一错误处理机制
|
||
3. **日志系统**:引入结构化日志
|
||
4. **配置管理**:统一配置管理
|
||
5. **中间件**:添加认证、限流等中间件
|
||
|
||
---
|
||
|
||
## 九、参考文档
|
||
|
||
- [Go 项目布局标准](https://github.com/golang-standards/project-layout)
|
||
- [Clean Architecture in Go](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
|
||
|