重构文件类型相关Service以支持国际化查询 添加findOneByLang辅助方法统一查询逻辑 实现StringConverter支持UI控件显示 优化缓存配置和查询性能 新增UnitStringConverter和CustomerCatalogStringConverter 完善文档和测试用例
124 lines
3.9 KiB
Markdown
124 lines
3.9 KiB
Markdown
# 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的同步更新,确保字段变更时转换逻辑也相应更新 |