重构文件类型相关Service以支持国际化查询 添加findOneByLang辅助方法统一查询逻辑 实现StringConverter支持UI控件显示 优化缓存配置和查询性能 新增UnitStringConverter和CustomerCatalogStringConverter 完善文档和测试用例
3.9 KiB
3.9 KiB
StringConverter 创建规则与实现逻辑
目的
StringConverter 在 Contract-Manager 项目中用于:
- 在UI组件(如ComboBox)中显示对象的可读字符串表示
- 从用户输入的字符串中还原对应的对象实例
- 支持表单数据的绑定和转换
创建规则
1. 文件位置
StringConverter 类应位于 com.ecep.contract.converter 包下
2. 命名规范
- 类名格式:
[EntityName]StringConverter - 例如:
CustomerCatalogStringConverter、VendorCatalogStringConverter
3. 继承关系
- 实现
javafx.util.StringConverter<T>接口,其中T为实体的VO类型 - 例如:
StringConverter<CustomerCatalogVo>
4. 构造函数
- 通常需要注入对应的Service实例
- 构造函数接收Service作为参数
- 例如:
public CustomerCatalogStringConverter(CustomerCatalogService service)
5. 核心方法实现
toString(T object)
- 将对象转换为可读的字符串表示
- 通常返回对象的名称或关键标识
- 处理null情况
fromString(String string)
- 从字符串还原对象实例
- 通常调用Service的findByName或findByCode方法
与Service类的关联
1. 在Service类中创建Converter实例
@Service
@CacheConfig(cacheNames = "[entity-name]-cache")
public class [EntityName]Service extends QueryService<[EntityName]Vo, [EntityName]ViewModel> {
private final [EntityName]StringConverter stringConverter = new [EntityName]StringConverter(this);
// 实现findByName方法供StringConverter使用
public [EntityName]Vo findByName(String name) {
return findAll(ParamUtils.builder().equals("name", name).build(), Pageable.ofSize(1))
.stream().findFirst().orElse(null);
}
@Override
public StringConverter<[EntityName]Vo> getStringConverter() {
return stringConverter;
}
}
2. 缓存配置
Service类通常需要添加缓存注解以提高性能:
@Cacheable(key = "#id")用于findById方法@Cacheable(key = "'all'")用于findAll方法@Caching(evict = {@CacheEvict(key = "'all'"), @CacheEvict(key = "#entity.id")})用于save和delete方法
示例实现
CustomerCatalogStringConverter 示例
package com.ecep.contract.converter;
import com.ecep.contract.service.CustomerCatalogService;
import com.ecep.contract.vo.CustomerCatalogVo;
import javafx.util.StringConverter;
public class CustomerCatalogStringConverter extends StringConverter<CustomerCatalogVo> {
private final CustomerCatalogService service;
public CustomerCatalogStringConverter(CustomerCatalogService service) {
this.service = service;
}
@Override
public String toString(CustomerCatalogVo object) {
return object == null ? "" : object.getName();
}
@Override
public CustomerCatalogVo fromString(String string) {
return service.findByName(string);
}
}
使用场景
在UI组件中的使用
StringConverter 主要用于:
- ComboBox的数据绑定和显示
- 表单字段的字符串转换
- 表格单元格的格式化显示
获取StringConverter实例
// 方式1:直接从Service获取
StringConverter<CustomerCatalogVo> converter = customerCatalogService.getStringConverter();
// 方式2:通过Spring容器获取
StringConverter<CustomerCatalogVo> converter = context.getBean(CustomerCatalogStringConverter.class);
常见模式
- 基础模式:直接继承StringConverter,实现toString和fromString方法
- 组件模式:继承EntityStringConverter基类,设置初始化、建议和字符串转换方法
- 枚举模式:针对枚举类型的特殊处理
注意事项
- 确保Service类实现了必要的find方法(如findByName)
- 处理null值情况,避免空指针异常
- 考虑缓存策略,提高频繁转换场景下的性能
- 保持Converter与Service的同步更新,确保字段变更时转换逻辑也相应更新