refactor(service): 统一Service缓存为VO对象并优化关联实体处理
重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。 调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
This commit is contained in:
@@ -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接口**:
|
||||
- 泛型参数:Vo(VO类类型)
|
||||
- 核心方法:findById、findAll、count
|
||||
- 职责:提供基于JSON参数的查询功能,返回VO对象
|
||||
|
||||
3. **VoableService接口**:
|
||||
- 泛型参数:M(实体类类型)、Vo(VO类类型)
|
||||
- 核心方法: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注解清理相关缓存
|
||||
- 确保缓存与数据库数据的一致性
|
||||
Reference in New Issue
Block a user