Files
contract-manager/docs/task/string_converter_implementation_guide.md
songqq 09b0da498b feat(service): 实现国际化支持并优化Service层
重构文件类型相关Service以支持国际化查询
添加findOneByLang辅助方法统一查询逻辑
实现StringConverter支持UI控件显示
优化缓存配置和查询性能
新增UnitStringConverter和CustomerCatalogStringConverter
完善文档和测试用例
2025-09-24 16:20:49 +08:00

124 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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实例
```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<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实例
```java
// 方式1直接从Service获取
StringConverter<CustomerCatalogVo> converter = customerCatalogService.getStringConverter();
// 方式2通过Spring容器获取
StringConverter<CustomerCatalogVo> converter = context.getBean(CustomerCatalogStringConverter.class);
```
## 常见模式
1. **基础模式**直接继承StringConverter实现toString和fromString方法
2. **组件模式**继承EntityStringConverter基类设置初始化、建议和字符串转换方法
3. **枚举模式**:针对枚举类型的特殊处理
## 注意事项
1. 确保Service类实现了必要的find方法如findByName
2. 处理null值情况避免空指针异常
3. 考虑缓存策略,提高频繁转换场景下的性能
4. 保持Converter与Service的同步更新确保字段变更时转换逻辑也相应更新