重构模型类包结构,将模型类按功能模块划分到不同的子包中。优化序列化处理,为VO类添加serialVersionUID并实现Serializable接口。移除部分冗余的serialVersionUID字段,简化模型类代码。同时修复UITools中空值处理的问题,并更新pom版本至0.0.100-SNAPSHOT。 - 将模型类按功能模块划分到ds子包中 - 为VO类添加序列化支持 - 移除冗余的serialVersionUID字段 - 修复UITools空值处理问题 - 更新项目版本号
7.0 KiB
7.0 KiB
客户端转换器类规则
1. 目录结构
- 所有类型转换器类必须位于
com.ecep.contract.converter包下 - 按照实体类型组织,无需进一步分包
2. 命名规范
- 类名格式:
[EntityName]StringConverter - 例如:
ContractStringConverter、CompanyStringConverter、VendorStringConverter
3. 继承关系
3.1 基础转换器类型
- 直接继承
javafx.util.StringConverter<T>接口 - 适用于简单的转换场景
- 例如:
public class ContractStringConverter extends StringConverter<ContractVo> {
// 实现代码
}
3.2 增强转换器类型
- 继承自定义的
EntityStringConverter<T>抽象类 - 适用于需要更多功能(如延迟初始化、搜索建议等)的场景
- 大多数业务实体转换器应使用此类型
- 例如:
public class CompanyStringConverter extends EntityStringConverter<CompanyVo> {
// 实现代码
}
3.3 枚举转换器类型
- 继承
EnumEntityStringConverter<E extends Enum<?>, T extends BaseEnumEntity<E>> - 专门用于处理枚举类型实体
- 例如:
public class EnumEntityStringConverter<E extends Enum<?>, T extends BaseEnumEntity<E>> extends StringConverter<T> {
// 实现代码
}
4. 核心接口实现
4.1 StringConverter 接口
- 所有转换器必须实现
toString(T object)方法 - 所有转换器必须实现
fromString(String string)方法
5. Spring框架集成
5.1 组件注解
- 增强转换器类型通常使用
@Component注解标记为Spring组件 - 结合
@Lazy注解实现延迟加载 - 例如:
@Lazy
@Component
public class CompanyStringConverter extends EntityStringConverter<CompanyVo> {
// 实现代码
}
5.2 依赖注入
- 使用
@Autowired注解注入对应的Service实例 - 通常也需要为注入的Service添加
@Lazy注解 - 例如:
@Lazy
@Autowired
private CompanyService service;
6. 初始化机制
6.1 构造函数
- 基础转换器通常使用构造函数接收Service实例
- 例如:
public ContractStringConverter(ContractService service) {
this.service = service;
}
6.2 初始化方法
- 增强转换器使用
@PostConstruct注解标记初始化方法 - 在初始化方法中配置转换器的各种功能
- 例如:
@PostConstruct
private void init() {
setInitialized(project -> service.findById(project.getId()));
setSuggestion(service::search);
setFromString(service::findByName);
}
7. EntityStringConverter 特性配置
继承自 EntityStringConverter 的增强转换器可以配置以下特性:
7.1 对象初始化
- 使用
setInitialized(Function<T, T> initialized)配置对象延迟初始化逻辑 - 通常调用Service的findById方法
- 例如:
setInitialized(project -> service.findById(project.getId()))
7.2 搜索建议
- 使用
setSuggestion(Function<String, List<T>> suggestion)配置自动补全数据提供方法 - 通常调用Service的search方法
- 例如:
setSuggestion(service::search)
7.3 字符串转换
- 使用
setFromString(Function<String, T> fromString)配置从字符串到对象的转换逻辑 - 通常调用Service的findByName方法
- 例如:
setFromString(service::findByName)
7.4 格式化器
- 使用
setFormater(Function<T, String> formater)配置自定义格式化逻辑 - 用于自定义对象的字符串表示
- 例如:
setFormater(contract -> contract.getCode() + " " + contract.getName())
8. 核心方法实现规范
8.1 toString(T object) 方法
- 将对象转换为可读的字符串表示
- 必须处理null情况
- 通常返回对象的名称、编码或其他关键标识
- 对于基础转换器:
@Override
public String toString(ContractVo cc) {
return cc.getCode() + " " + cc.getName();
}
- 对于枚举转换器:
@Override
public String toString(T object) {
return object == null ? "" : object.getValue();
}
8.2 fromString(String string) 方法
- 从字符串还原对象实例
- 通常调用Service的findByName或findByCode方法
- 例如:
@Override
public ContractVo fromString(String string) {
return service.findByCode(string);
}
- 对于某些场景(如枚举转换器),可能返回null
9. 与Service类的关联
9.1 Service中的转换器创建
- 在Service类中通常会创建并持有对应的StringConverter实例
- 实现
getStringConverter()方法返回转换器实例 - 例如:
@Service
@CacheConfig(cacheNames = "contract-cache")
public class ContractService extends QueryService<ContractVo, ContractViewModel> {
private final ContractStringConverter stringConverter = new ContractStringConverter(this);
@Override
public StringConverter<ContractVo> getStringConverter() {
return stringConverter;
}
}
9.2 Service方法支持
- Service需提供
findByName、findById、search等方法供转换器使用 - 这些方法通常需要添加缓存注解以提高性能
10. 使用场景
StringConverter主要用于以下场景:
- ComboBox、ChoiceBox等选择组件的数据绑定和显示
- 表单数据的绑定和转换
- 支持用户输入的自动补全功能
- 在表格、列表等UI组件中显示对象的可读表示
11. 最佳实践
- 对于大多数业务实体,优先使用继承
EntityStringConverter<T>的增强转换器 - 使用Spring的依赖注入和组件管理功能
- 正确处理null值和空字符串
- 为频繁调用的Service方法添加缓存支持
- 实现合理的toString逻辑,提供有意义的对象表示
12. 示例代码结构
12.1 基础转换器示例
package com.ecep.contract.converter;
import com.ecep.contract.service.ContractService;
import com.ecep.contract.vo.ContractVo;
import javafx.util.StringConverter;
public class ContractStringConverter extends StringConverter<ContractVo> {
private final ContractService service;
public ContractStringConverter(ContractService service) {
this.service = service;
}
@Override
public String toString(ContractVo cc) {
return cc == null ? "" : cc.getCode() + " " + cc.getName();
}
@Override
public ContractVo fromString(String string) {
return string == null || string.isEmpty() ? null : service.findByCode(string);
}
}
12.2 增强转换器示例
package com.ecep.contract.converter;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.vo.CompanyVo;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Lazy
@Component
public class CompanyStringConverter extends EntityStringConverter<CompanyVo> {
@Lazy
@Autowired
private CompanyService service;
@PostConstruct
private void init() {
setInitialized(company -> service.findById(company.getId()));
setSuggestion(service::search);
setFromString(service::findByName);
}
}