You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将不同类作为方法参数传入,通过泛型获取实体类数据?

完全可以实现,核心思路是先把所有实体类的公共属性访问逻辑抽象到统一接口层,再配合泛型限定就可以去掉冗余的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 11:36:03