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

Spring如何编写通用服务类返回对应表的JDBC批量更新实现类对象

可行实现方案

1. 定义核心基础组件

首先定义标识表名的注解和统一批量更新接口,规范所有更新器的实现标准:

// 表更新器标识注解,作用在实现类上指定对应的表名
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface TableUpdater {
    String value();
}

// 统一批量更新接口
public interface BaseBatchUpdater<T> {
    void updateBatch(List<T> dataList);
}

2. 实现批量更新器

支持两种实现模式,满足不同表的逻辑需求:

有自定义逻辑的表单独实现

// TableA的专属批量更新器,直接加注解指定表名即可,无需修改其他业务代码
@TableUpdater("TableA")
public class TableABatchUpdater implements BaseBatchUpdater<TableAEntity> {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void updateBatch(List<TableAEntity> dataList) {
        // 自定义TableA的批量更新逻辑
        String sql = "update table_a set column1 = ?, column2 = ? where id = ?";
        jdbcTemplate.batchUpdate(sql, dataList, dataList.size(), (ps, entity) -> {
            ps.setObject(1, entity.getColumn1());
            ps.setObject(2, entity.getColumn2());
            ps.setObject(3, entity.getId());
        });
    }
}

无特殊逻辑的表用通用实现

无需单独写实现类,直接复用通用更新器:

public class CommonBatchUpdater<T> implements BaseBatchUpdater<T> {
    private final JdbcTemplate jdbcTemplate;
    private final String updateSql;
    private final Function<T, Object[]> paramMapper;

    public CommonBatchUpdater(JdbcTemplate jdbcTemplate, String updateSql, Function<T, Object[]> paramMapper) {
        this.jdbcTemplate = jdbcTemplate;
        this.updateSql = updateSql;
        this.paramMapper = paramMapper;
    }

    @Override
    public void updateBatch(List<T> dataList) {
        jdbcTemplate.batchUpdate(updateSql, dataList.stream().map(paramMapper).toList());
    }
}

3. 实现统一调度服务BatchUpdaterService

自动收集所有更新器实例,构建表名和更新器的映射关系:

@Service
public class BatchUpdaterService {
    private final Map<String, BaseBatchUpdater<?>> updaterMap = new HashMap<>();
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // Spring自动注入所有BaseBatchUpdater的实现类
    @Autowired
    public BatchUpdaterService(List<BaseBatchUpdater<?>> customUpdaters) {
        // 先注册自定义实现的更新器
        customUpdaters.forEach(updater -> {
            TableUpdater anno = updater.getClass().getAnnotation(TableUpdater.class);
            if (anno != null) {
                updaterMap.put(anno.value(), updater);
            }
        });
        // 注册通用实现的更新器,新增无特殊逻辑的表只需要在这里加一行即可
        registerCommonUpdater("TableD", "update table_d set col = ? where id = ?", 
            (TableDEntity entity) -> new Object[]{entity.getCol(), entity.getId()});
    }

    private <T> void registerCommonUpdater(String tableName, String sql, Function<T, Object[]> paramMapper) {
        updaterMap.put(tableName, new CommonBatchUpdater<>(jdbcTemplate, sql, paramMapper));
    }

    @SuppressWarnings("unchecked")
    public <T> BaseBatchUpdater<T> getTableUpdater(String tableName) {
        BaseBatchUpdater<?> updater = updaterMap.get(tableName);
        if (updater == null) {
            throw new IllegalArgumentException("未找到对应表的批量更新器: " + tableName);
        }
        return (BaseBatchUpdater<T>) updater;
    }
}

4. 业务侧使用

和你预期的调用逻辑完全一致,后续新增表不需要修改这段代码:

@Service
public class MyServiceClass {
    @Autowired 
    private BatchUpdaterService batchUpdaterService;
    
    public void updateTables() {
        batchUpdaterService.getTableUpdater("TableA").updateBatch(tableAList);
        batchUpdaterService.getTableUpdater("TableB").updateBatch(tableBList);
        batchUpdaterService.getTableUpdater("TableC").updateBatch(tableCList);
        // 新增TableD直接加下面一行即可,不需要改动当前类的依赖注入
        // batchUpdaterService.getTableUpdater("TableD").updateBatch(tableDList);
    }
}

优化建议

  • 可以在getTableUpdater方法中增加实体类型校验,避免泛型强制转换的运行时异常
  • 配合MyBatis-Plus等ORM框架使用的话,可以直接复用框架内置的批量更新能力,进一步简化通用实现的代码
  • 可将通用更新器的配置(表名、更新SQL、参数映射规则)存入配置文件,启动时自动扫描注册,新增通用表连BatchUpdaterService的代码都不需要修改

内容的提问来源于stack exchange,提问作者Pamuleti Pullagura

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:45:02