refactor(service): 统一Service缓存为VO对象并优化关联实体处理

重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。

调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
This commit is contained in:
2025-09-29 19:31:51 +08:00
parent 64471b46f8
commit 49413ad473
167 changed files with 6840 additions and 1811 deletions

View File

@@ -0,0 +1,371 @@
# Server模块Service缓存调整为Vo对象 - DESIGN文档
## 1. 整体架构图
```mermaid
flowchart TD
subgraph Client层
Client["JavaFX客户端"]
end
subgraph 表示层
WS["WebSocketServerHandler"]
WSCB["WebSocketServerCallbackManager"]
WSCT["WebSocketServerTaskManager"]
Controller["RESTful Controller"]
end
subgraph 业务层
Service["Service类
(@CacheConfig注解)"]
IES["IEntityService接口"]
QS["QueryService接口"]
VS["VoableService接口"]
end
subgraph 数据访问层
Repository["JPA Repository"]
end
subgraph 数据存储层
MySQL["MySQL数据库"]
Redis["Redis缓存"]
end
Client -->|WebSocket| WS
WS -->|处理会话| WSCT
WS -->|处理消息| WSCB
WSCB -->|动态调用| Service
Controller -->|调用| Service
Service -->|实现| IES
Service -->|实现| QS
Service -->|实现| VS
Service -->|CRUD操作| Repository
Repository -->|持久化| MySQL
Service -->|缓存操作| Redis
```
## 2. 分层设计和核心组件
### 2.1 分层设计
系统采用经典的三层架构,每层职责明确:
1. **数据存储层**
- MySQL数据库存储系统的持久化数据
- Redis缓存存储VO对象缓存提高系统性能
2. **数据访问层**
- JPA Repository接口提供对数据库的访问操作
- 主要职责执行SQL查询管理实体对象的生命周期
3. **业务层**
- Service类实现业务逻辑管理缓存
- 核心接口IEntityService、QueryService、VoableService
- 主要职责处理业务规则管理实体与VO的转换缓存管理
4. **表示层**
- WebSocket服务处理客户端WebSocket连接和消息
- RESTful Controller处理HTTP请求
- 主要职责:接收和响应客户端请求,调用业务层服务
### 2.2 核心组件
#### 2.2.1 Service层组件
1. **IEntityService接口**
- 泛型参数T实体类类型
- 核心方法getById、findAll、save、delete
- 职责提供对实体类的基本CRUD操作
2. **QueryService接口**
- 泛型参数VoVO类类型
- 核心方法findById、findAll、count
- 职责提供基于JSON参数的查询功能返回VO对象
3. **VoableService接口**
- 泛型参数M实体类类型、VoVO类类型
- 核心方法updateByVo
- 职责提供将VO对象的属性更新到实体对象的功能
4. **Service实现类**
- 特点:实现多个接口,使用@CacheConfig等注解配置缓存
- 职责:实现业务逻辑,管理缓存
#### 2.2.2 WebSocket组件
1. **WebSocketServerHandler**
- 职责管理WebSocket会话处理连接的建立和关闭
- 依赖WebSocketServerTaskManager、WebSocketServerCallbackManager
2. **WebSocketServerTaskManager**
- 职责加载和管理WebSocket任务类处理会话任务
3. **WebSocketServerCallbackManager**
- 职责处理客户端发送的消息调用相应的Service方法
- 特点通过反射机制动态调用Service方法
## 3. 模块依赖关系图
```mermaid
flowchart TD
subgraph WebSocket模块
WSH[WebSocketServerHandler]
WSTM[WebSocketServerTaskManager]
WSCM[WebSocketServerCallbackManager]
end
subgraph Service接口模块
IES[IEntityService接口]
QS[QueryService接口]
VS[VoableService接口]
end
subgraph Service实现模块
SImpl[Service实现类]
end
subgraph 数据访问模块
Repo[JPA Repository]
end
subgraph 缓存模块
Redis[Redis缓存]
end
WSH --> WSTM
WSH --> WSCM
WSCM --> SImpl
SImpl --> IES
SImpl --> QS
SImpl --> VS
SImpl --> Repo
SImpl --> Redis
```
## 4. 接口契约定义
### 4.1 IEntityService接口
```java
public interface IEntityService<T> {
/**
* 根据ID获取实体对象
* @param id 实体ID
* @return 实体对象
* 注意:有关联实体时不能使用@Cacheable注解
*/
T getById(Integer id);
/**
* 根据条件查询实体对象列表
* @param spec 查询条件
* @param pageable 分页参数
* @return 分页结果
*/
Page<T> findAll(Specification<T> spec, Pageable pageable);
/**
* 根据搜索文本构建查询条件
* @param searchText 搜索文本
* @return 查询条件
*/
Specification<T> getSpecification(String searchText);
/**
* 根据搜索文本搜索实体对象
* @param searchText 搜索文本
* @return 实体对象列表
*/
default List<T> search(String searchText);
/**
* 删除实体对象
* @param entity 实体对象
*/
void delete(T entity);
/**
* 保存实体对象
* @param entity 实体对象
* @return 保存后的实体对象
*/
T save(T entity);
}
```
### 4.2 QueryService接口
```java
public interface QueryService<Vo> {
/**
* 根据ID获取VO对象
* @param id 实体ID
* @return VO对象
*/
Vo findById(Integer id);
/**
* 根据JSON参数查询VO对象列表
* @param paramsNode JSON参数
* @param pageable 分页参数
* @return 分页结果
*/
Page<Vo> findAll(JsonNode paramsNode, Pageable pageable);
/**
* 根据JSON参数统计数量
* @param paramsNode JSON参数
* @return 数量
*/
default long count(JsonNode paramsNode);
}
```
### 4.3 VoableService接口
```java
public interface VoableService<M, Vo> {
/**
* 将VO对象的属性更新到实体对象
* @param model 实体对象
* @param vo VO对象
*/
void updateByVo(M model, Vo vo);
}
```
### 4.4 WebSocketServerCallbackManager关键方法
```java
public class WebSocketServerCallbackManager {
/**
* 处理findAll方法调用
*/
private Object invokerFindAllMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理findById方法调用
*/
private Object invokerFindByIdMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理save方法调用
*/
private Object invokerSaveMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理delete方法调用
*/
private Object invokerDeleteMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 创建新实体对象
*/
private Object createNewEntity(String serviceName, JsonNode paramsNode) {
// 实现逻辑
}
}
```
## 5. 数据流向图
### 5.1 查询数据流程
```mermaid
flowchart TD
Client[客户端] -->|发送查询请求| WS[WebSocketServerHandler]
WS -->|处理请求| WSCB[WebSocketServerCallbackManager]
WSCB -->|动态调用| Service[Service实现类]
Service -->|查询缓存| Redis[Redis缓存]
Redis -->|命中缓存| Service
Service -->|未命中缓存| Repo[JPA Repository]
Repo -->|查询数据库| MySQL[MySQL数据库]
MySQL -->|返回实体| Repo
Repo -->|返回实体| Service
Service -->|实体转VO| Service
Service -->|缓存VO| Redis
Service -->|返回VO| WSCB
WSCB -->|返回结果| WS
WS -->|发送响应| Client
```
### 5.2 更新数据流程
```mermaid
flowchart TD
Client[客户端] -->|发送更新请求| WS[WebSocketServerHandler]
WS -->|处理请求| WSCB[WebSocketServerCallbackManager]
WSCB -->|动态调用| Service[Service实现类]
Service -->|清理缓存| Redis[Redis缓存]
Service -->|调用updateByVo| Service
Service -->|保存实体| Repo[JPA Repository]
Repo -->|更新数据库| MySQL[MySQL数据库]
MySQL -->|返回结果| Repo
Repo -->|返回实体| Service
Service -->|实体转VO| Service
Service -->|缓存VO| Redis
Service -->|返回VO| WSCB
WSCB -->|返回结果| WS
WS -->|发送响应| Client
```
## 6. 异常处理策略
### 6.1 全局异常处理
- 使用@ControllerAdvice注解定义全局异常处理器
- 处理常见的异常类型,如数据不存在、参数错误等
- 返回统一的错误响应格式
### 6.2 业务层异常处理
- Service类中捕获并处理业务逻辑异常
- 向上层抛出经过包装的业务异常
- 记录异常日志
### 6.3 WebSocket异常处理
- WebSocketServerHandler中捕获并处理WebSocket相关异常
- 关闭异常会话,避免影响其他会话
- 记录异常日志
### 6.4 缓存异常处理
- 捕获并处理Redis相关异常
- 当缓存不可用时,降级为直接查询数据库
- 记录异常日志,便于问题排查
## 7. 关键设计决策
### 7.1 缓存键设计
采用`{cacheName}:{entityType}:{id}`格式的缓存键,其中:
- `cacheName`:通过@CacheConfig指定的缓存名称
- `entityType`:实体类的简单名称
- `id`实体的ID值
### 7.2 缓存值转换
- 在Service类的findById、findAll等方法中先查询实体对象然后转换为Vo对象
- 将转换后的Vo对象存入缓存
- 确保存入缓存的Vo对象是可序列化的
### 7.3 关联实体处理
- 在updateByVo方法中添加实体匹配检查逻辑
- 使用getById方法获取关联实体避免直接使用findById
- 对于为null的关联ID不执行查询操作
### 7.4 缓存清理策略
- 在save、delete等修改数据的方法中使用@CacheEvict或@Caching注解清理相关缓存
- 确保缓存与数据库数据的一致性