Bootstrap

使用SpringJdbcTemplate进行批量的更新/新增(高效率)

refer:几种批量删除分析比较:https://blog.csdn.net/fbysss/article/details/4152703?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.control

参考2:https://www.cnblogs.com/lzfhope/p/12069758.html

使用JDBC的进行Batch操作的缘由

由于数据的批量处理(比如往RDBMS插入几万条数据)非常耗资源,因此建议在所有场合能够借助于JDBC完成,而不要去采用Hibernate API。本文主要围绕Spring内置的各类JDBC API抽象支持展开的。

方式一:JdbcTemplate内置的batchUpdate()方法

batchUpdate(String sql, final BatchPreparedStatementSetter pss)

这一方法也仅仅适合于小批量数据的CUD(增、更新、删除)操作,但始终是同一SQL(参数具有多样性)。由于其内部使用了PreparedStatement语句,所以数据的操作效率还是不错的。下面给出了操作示例:

    public Object batchUpdateUser(List<User> users){
        jdbcTemplate.batchUpdate(" UPDATE user SET number = ? WHERE name = ? ",
                new BatchPreparedStatementSetter(){
                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, users.get(i).getNumber());
                        ps.setString(2, users.get(i).getName());
                    }
                    @Override
                    public int getBatchSize() {
                        return users.size();
                    }
                });
        return "OK";
    }

    public Object insert(List<User> users){
        jdbcTemplate.batchUpdate(" insert into user(name,number) values (?,?) ",
                new BatchPreparedStatementSetter(){
                    @Override
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        ps.setString(1, users.get(i).getName());
                        ps.setString(2, users.get(i).getNumber());
                    }
                    @Override
                    public int getBatchSize() {
                        return users.size();
                    }
                });
        return "OK";
    }

方式二:BatchSqlUpdate

这一方法适合于各种批量数据的CUD(增、更新、删除)操作,但始终是同一SQL(参数具有多样性)。由于其内部使用了PreparedStatement语句,所以数据的操作效率还是不错的。下面给出了操作示例:

public Object insert2(List<User> users){
        DataSource dataSource = jdbcTemplate.getDataSource();
        BatchSqlUpdate bsu = new BatchSqlUpdate(dataSource, " insert into user(name,number) values (?,?)");
        bsu.setBatchSize(1000);
        bsu.setTypes(new int[]{Types.VARCHAR, Types.VARCHAR});

        for (User user : users) {
            bsu.update(new Object[]{user.getName(), user.getName()});
        }
        bsu.flush();
        return "OK";
    }

JdbcTemplate内置的batchUpdate(String sql, final BatchPreparedStatementSetter pss)相比,BatchSqlUpdate会自动分批待批量处理的数据。比如,如果需要批量操作10万条数据,则可以控制其batchSize,从而在时间(RDBMS可知性)和空间(内存)上达到平衡。

务必注意,在使用BatchSqlUpdate的最后,不要忘记手工调用其暴露的flush()方法。

使用sql语句 case when

/**
     * 批量更新人员Status
     *
     * @param personList personList
     */
    public void updatePersonStatusBatch(List<EcssPerson> personList) {

        String sql = " Update t_ecss_person Set ";
        sql += " n_last_update_status = case n_id ";
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilder2 = new StringBuilder();
        StringBuilder ids = new StringBuilder();
        int i = 1;
        for (EcssPerson person : personList) {
            stringBuilder.append("  when " + person.getId() +
                    "  then " + person.getLastUpdateStatus());
            if (i == personList.size()) {
                stringBuilder.append(" end,");
                stringBuilder.append(" c_ec_code= ");
            }
            if(i==1){
                stringBuilder2.append(" case n_id ");
            }
            stringBuilder2.append(
                    "   when " + person.getId() +
                            "  then " + person.getEcCode());
            if (i == personList.size()) {
                stringBuilder2.append(" end ");
            }
            ids.append(person.getId());
            ids.append(",");
            i++;
        }
        stringBuilder.append(stringBuilder2);
        sql += stringBuilder.toString()+"  where n_id in (" + ids.toString().substring(0, ids.length() - 1) + ")";
        System.out.println(sql);
        this.executeSql(sql, new MapSqlParameterSource());
    }
;