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

QueryDsl使用两个List参数完成批量更新的实现方案咨询

可行解决方案
  • 方案1:使用QueryDSL的Case When语法拼接单次更新语句
    该方案可以生成单条UPDATE语句一次提交执行,无需循环向数据库发送请求,适合单次更新条数小于1000的场景,避免SQL语句过长。
    代码示例:

    // 先定义接收ID和对应账号的DTO类
    public class EmployeeAccountDTO {
        private Long id;
        private String account;
        // 省略get、set方法
    }
    
    // 调整后的更新方法
    public void updateEmployeeData(List<EmployeeAccountDTO> employeeAccountList) {
        CaseBuilder.Cases<String, String> cases = new CaseBuilder.Cases<>(String.class);
        // 遍历拼接所有ID和账号的映射规则
        for (EmployeeAccountDTO dto : employeeAccountList) {
            cases = cases.when(employee.employeeId.eq(dto.getId())).then(dto.getAccount());
        }
        // 提取所有需要更新的ID集合作为过滤条件,避免全表扫描
        List<Long> idList = employeeAccountList.stream()
                .map(EmployeeAccountDTO::getId)
                .toList();
        queryFactory.update(employee)
                .set(employee.employeeAccount, cases.otherwise(employee.employeeAccount))
                .where(employee.employeeId.in(idList))
                .execute();
    }
    

    最终生成的SQL逻辑如下:

    UPDATE employee 
    SET employee_account = CASE 
        WHEN employee_id = 1 THEN '账号1' 
        WHEN employee_id = 2 THEN '账号2'
        ...
        ELSE employee_account END
    WHERE employee_id IN (1,2,...)
    
  • 方案2:使用JDBC批量更新
    适合更新量较大的场景,将多条更新语句攒为一批提交到数据库,减少多次网络往返的开销,性能远高于循环单条执行。
    代码示例:

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public void updateEmployeeData(List<EmployeeAccountDTO> employeeAccountList) {
        String updateSql = "UPDATE employee SET employee_account = ? WHERE employee_id = ?";
        jdbcTemplate.batchUpdate(updateSql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int index) throws SQLException {
                EmployeeAccountDTO dto = employeeAccountList.get(index);
                ps.setString(1, dto.getAccount());
                ps.setLong(2, dto.getId());
            }
    
            @Override
            public int getBatchSize() {
                return employeeAccountList.size();
            }
        });
    }
    
  • 方案3:临时表关联更新
    适合单次更新上万条的超大规模场景,先将ID和账号的映射写入临时表,再通过表关联完成批量更新,性能最优。
    核心SQL逻辑:

    -- 创建临时表存储映射关系
    CREATE TEMPORARY TABLE temp_account_map (employee_id BIGINT, account VARCHAR(64));
    -- 批量插入映射数据
    INSERT INTO temp_account_map VALUES (1,'账号1'),(2,'账号2'),(3,'账号3'),...;
    -- 关联执行更新
    UPDATE employee e 
    INNER JOIN temp_account_map t ON e.employee_id = t.employee_id 
    SET e.employee_account = t.account;
    

内容的提问来源于stack exchange,提问作者John Hue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:06:03