重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。 调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
6.0 KiB
实体-VO转换机制与缓存策略实现分析报告
1. 概述
本报告是"实体-VO转换机制与缓存策略任务拆分"子任务1的执行结果,旨在分析Contract-Manager项目中实体-VO转换机制和Service类结构,为将Server模块Service缓存从实体对象调整为VO对象提供基础分析。
2. 核心接口体系分析
2.1 Voable接口
Voable<T>是实体类实现的核心接口,用于将实体转换为VO对象:
public interface Voable<T> {
/**
* 转换为Vo
*
* @return
*/
T toVo();
}
该接口非常简洁,只定义了一个toVo()方法,用于将实体对象转换为对应的VO对象。
2.2 QueryService接口
QueryService<Vo>是查询服务接口,提供通用的分页查询能力:
public interface QueryService<Vo> {
/**
* 根据ID查询单条数据
* @param id
* @return 符合ID的Vo对象,若不存在则返回null
*/
Vo findById(Integer id);
/**
* 根据查询参数和分页条件获取数据列表
*
* @param paramsNode JSON格式的查询参数节点,包含各种过滤条件
* @param pageable 分页参数,包含页码、每页条数、排序规则等信息
* @return 分页查询结果,包含符合条件的数据列表和分页元数据
*/
Page<Vo> findAll(JsonNode paramsNode, Pageable pageable);
/**
* 根据查询参数统计符合条件的数据总数
* @param paramsNode JSON格式的查询参数节点,包含各种过滤条件
* @return 符合条件的数据总数
*/
default long count(JsonNode paramsNode) {
return 0;
}
}
该接口的泛型参数Vo表示查询结果的数据类型,即View Object类,是可序列化、可持久的类。
2.3 VoableService接口
VoableService<M, Vo>是可转换为VO的服务接口:
public interface VoableService<M, Vo> {
void updateByVo(M model, Vo vo);
}
该接口定义了一个updateByVo()方法,用于根据VO对象更新对应的实体对象。
2.4 IEntityService接口
IEntityService<T>是实体服务接口,提供基础的CRUD操作:
public interface IEntityService<T> {
T getById(Integer id);
Page<T> findAll(Specification<T> specification, Pageable pageable);
Specification<T> getSpecification(String searchText);
List<T> search(String searchText);
void delete(T entity);
T save(T entity);
}
3. 实体-VO转换机制分析
以Contract实体和ContractVo为例,分析实体-VO转换机制:
3.1 实体类结构
Contract实体类实现了Voable<ContractVo>接口,表示它可以转换为ContractVo对象:
public class Contract
implements IdentityEntity, NamedEntity, BasedEntity, CompanyBasedEntity, Serializable, Voable<ContractVo> {
// 实体属性定义
// ...
}
3.2 VO类结构
ContractVo是一个简单的POJO类,使用@Data注解简化代码:
@Data
public class ContractVo implements IdentityEntity, NamedEntity, CompanyBasedVo, ProjectBasedVo {
// VO属性定义
// ...
}
3.3 转换实现
Contract类实现了toVo()方法,用于将实体转换为VO:
@Override
public ContractVo toVo() {
ContractVo vo = new ContractVo();
vo.setId(id);
vo.setGuid(getGuid());
vo.setCode(getCode());
vo.setName(name);
if (getCompany() != null) {
vo.setCompanyId(getCompany().getId());
}
if (group != null) {
vo.setGroupId(group.getId());
}
// ... 其他属性转换 ...
return vo;
}
转换实现遵循以下模式:
- 创建对应的VO对象
- 将实体的基本属性直接复制到VO对象
- 对于关联实体,只复制其ID而不是整个对象
- 返回填充好的VO对象
4. Service类结构与缓存策略分析
4.1 Service类继承关系
以ContractService为例,Service类通常继承自EntityService并实现多个接口:
@Service
@CacheConfig(cacheNames = "contract")
public class ContractService extends EntityService<Contract, Integer> implements QueryService<Contract>, VoableService<Contract, ContractVo> {
// Service方法实现
// ...
}
4.2 缓存配置
Service类使用@CacheConfig注解配置缓存名称:
@CacheConfig(cacheNames = "contract")
在Server模块中,共有58个Service类使用了@CacheConfig注解配置缓存。
4.3 缓存使用
查询方法通常使用@Cacheable注解缓存结果:
@Cacheable(key = "#id")
public Contract findById(Integer id) {
// 实现逻辑
}
增删改方法通常使用@Caching等注解清除缓存:
@Caching(evict = {
@CacheEvict(key = "#contract.id"),
@CacheEvict(cacheNames = "contract", key = "'findByCode_'.concat(#contract.code)")
})
public Contract save(Contract contract) {
// 实现逻辑
}
5. 发现的问题和改进点
5.1 缓存对象类型不一致
目前,部分Service类的缓存对象是实体对象,而不是VO对象,这与项目的设计理念不一致。
5.2 泛型参数使用不一致
部分Service类实现的QueryService接口泛型参数是实体类型,而不是VO类型。
5.3 转换逻辑重复
每个实体类都需要实现toVo()方法,存在大量重复代码。
5.4 关联实体处理
当前的转换逻辑对于关联实体只复制ID,可能无法满足复杂查询的需求。
6. 结论
通过分析,我们了解了Contract-Manager项目中的实体-VO转换机制和Service类结构。目前的实现存在一些不一致性和改进空间,特别是在缓存对象类型和泛型参数使用方面。
为了将Server模块Service缓存从实体对象调整为VO对象,我们需要:
- 统一Service类实现的接口泛型参数
- 修改缓存注解,确保缓存的是VO对象而不是实体对象
- 优化转换逻辑,减少重复代码
- 处理好关联实体的转换和缓存
本报告为后续的子任务提供了基础分析,帮助确定具体的实现方案和步骤。