# 数据库客户端后端架构设计文档 **文档版本**:v2.0 **维护者**:JueChen **更新日期**:2026-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)