# StringConverter 创建规则与实现逻辑 ## 目的 StringConverter 在 Contract-Manager 项目中用于: - 在UI组件(如ComboBox)中显示对象的可读字符串表示 - 从用户输入的字符串中还原对应的对象实例 - 支持表单数据的绑定和转换 ## 创建规则 ### 1. 文件位置 StringConverter 类应位于 `com.ecep.contract.converter` 包下 ### 2. 命名规范 - 类名格式:`[EntityName]StringConverter` - 例如:`CustomerCatalogStringConverter`、`VendorCatalogStringConverter` ### 3. 继承关系 - 实现 `javafx.util.StringConverter` 接口,其中T为实体的VO类型 - 例如:`StringConverter` ### 4. 构造函数 - 通常需要注入对应的Service实例 - 构造函数接收Service作为参数 - 例如:`public CustomerCatalogStringConverter(CustomerCatalogService service)` ### 5. 核心方法实现 #### toString(T object) - 将对象转换为可读的字符串表示 - 通常返回对象的名称或关键标识 - 处理null情况 #### fromString(String string) - 从字符串还原对象实例 - 通常调用Service的findByName或findByCode方法 ## 与Service类的关联 ### 1. 在Service类中创建Converter实例 ```java @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 示例 ```java 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 { 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实例 ```java // 方式1:直接从Service获取 StringConverter converter = customerCatalogService.getStringConverter(); // 方式2:通过Spring容器获取 StringConverter converter = context.getBean(CustomerCatalogStringConverter.class); ``` ## 常见模式 1. **基础模式**:直接继承StringConverter,实现toString和fromString方法 2. **组件模式**:继承EntityStringConverter基类,设置初始化、建议和字符串转换方法 3. **枚举模式**:针对枚举类型的特殊处理 ## 注意事项 1. 确保Service类实现了必要的find方法(如findByName) 2. 处理null值情况,避免空指针异常 3. 考虑缓存策略,提高频繁转换场景下的性能 4. 保持Converter与Service的同步更新,确保字段变更时转换逻辑也相应更新