如何将不同类作为方法参数传入,通过泛型获取实体类数据?
完全可以实现,核心思路是先把所有实体类的公共属性访问逻辑抽象到统一接口层,再配合泛型限定就可以去掉冗余的switch分支,实现你要的简洁写法,具体改造步骤如下:
步骤1:定义公共接口统一属性访问
因为你当前不同实体的部分属性名存在差异(比如Message的请求编号是getRequestNumber,Behavior的请求编号是getRegNumber),还有固定的实体显示名和类绑定,所以先定义一个继承BaseEntity的公共接口,抽象出所有需要用到的公共方法:
public interface StatusTrackable extends BaseEntity { // 统一请求编号的获取方法,不同实体各自适配自身属性 String getRequestNumber(); // 统一状态获取 Status getStatus(); // 统一发起人获取 PersonGroupExt getInitiator(); // 统一实体显示名获取(对应你原来的"Сообщения"/"Обращения"常量) String getEntityDisplayName(); // 默认实现获取实体类名,对应你原来的entityName字段 default String getEntityName() { return this.getClass().getSimpleName(); } }
所有涉及的实体类都实现这个接口,按需适配自身属性即可:
// Message类实现示例 public class Message extends BaseEntity implements StatusTrackable { // 原有属性和方法不变 @Override public String getRequestNumber() { return this.getRequestNumber(); } @Override public String getEntityDisplayName() { return "Сообщения"; } // 其他接口方法直接返回自身对应属性即可 } // Behavior类实现示例 public class Behavior extends BaseEntity implements StatusTrackable { // 原有属性和方法不变 @Override public String getRequestNumber() { // 适配自身的注册编号属性 return this.getRegNumber(); } @Override public String getEntityDisplayName() { return "Обращения"; } // 其他接口方法直接返回自身对应属性即可 }
步骤2:改造目标方法
根据你的使用场景,可以选择两种实现方式:
方式1:直接传入已加载的实体对象(最简洁)
// 泛型限定传入的实体必须实现StatusTrackable接口 public <T extends StatusTrackable> String sendChangedStatus(T entity) throws ExecutionException, InterruptedException { // 直接通过统一接口获取所有需要的属性,完全不需要类型判断 String requestNumber = entity.getRequestNumber(); String name = entity.getEntityDisplayName(); String status = entity.getStatus().getLangValue(); String entityName = entity.getEntityName(); PersonGroupExt initiator = entity.getInitiator(); // 原有后续业务逻辑 // ... }
方式2:传入类+ID,方法内部自动加载实体
如果不想在方法外加载实体,可以提前配置每个类对应的查询参数,方法内部自动处理加载逻辑:
首先定义查询配置和配置映射:
@Getter @AllArgsConstructor public static class EntityQueryConfig { private String querySql; private String viewName; } // 存储每个实体类对应的查询配置,新增实体只需要加一条配置即可 private static final Map<Class<? extends StatusTrackable>, EntityQueryConfig> QUERY_CONFIG_MAP = Map.of( Message.class, new EntityQueryConfig("select e from hse_Message e where e.id = :entityId", "message-editView"), Behavior.class, new EntityQueryConfig("select e from hse_Behavior e where e.id = :entityId", null) );
然后改造方法:
public <T extends StatusTrackable> String sendChangedStatus(Class<T> entityClass, UUID entityId) throws ExecutionException, InterruptedException { EntityQueryConfig config = QUERY_CONFIG_MAP.get(entityClass); if (config == null) { throw new IllegalArgumentException("不支持的实体类型:" + entityClass.getSimpleName()); } // 按配置加载对应实体 T entity; if (config.getViewName() != null) { entity = dataManager.load(entityClass) .query(config.getQuerySql()) .parameter("entityId", entityId) .view(config.getViewName()) .optional().orElse(null); } else { entity = dataManager.loadValue(config.getQuerySql(), entityClass) .parameter("entityId", entityId) .optional().orElse(null); } if (entity == null) { // 自定义处理实体不存在的逻辑 return ""; } // 和方式1一致,直接获取属性即可 String requestNumber = entity.getRequestNumber(); String name = entity.getEntityDisplayName(); String status = entity.getStatus().getLangValue(); String entityName = entity.getEntityName(); PersonGroupExt initiator = entity.getInitiator(); // 原有后续业务逻辑 // ... }
改造完成后完全不需要维护冗长的switch分支,后续新增同类型实体时,只要实现StatusTrackable接口,按需添加查询配置即可,核心业务逻辑不需要改动。
内容的提问来源于stack exchange,提问作者Danik
相关产品推荐
相关产品推荐

