JdbcTemplate的四种批处理的用法

JdbcTemplate批量写入方法详解

再做详解之前,我们先来了解一下JdbcTemplate批量操作的5个API接口:

一. 使用提供的SQL语句执行批处理

这个方法相对来说比较简单,不做详细解析,该方法主要是将提供的sql列表作为一个batch进行执行,每个sql的update count可以通过返回int[]的长度计算来获得

二. 使用批处理更新和BatchPreparedStatementSetter

1. 接口API源码

int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) throws DataAccessException;

2. 接口API源码实现

public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL batch update [" + sql + "]");
		}

		int[] result = execute(sql, (PreparedStatementCallback<int[]>) ps -> {
			try {
				int batchSize = pss.getBatchSize();
				InterruptibleBatchPreparedStatementSetter ipss =
						(pss instanceof InterruptibleBatchPreparedStatementSetter ?
						(InterruptibleBatchPreparedStatementSetter) pss : null);
				if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
					for (int i = 0; i < batchSize; i++) {
						pss.setValues(ps, i);
						if (ipss != null && ipss.isBatchExhausted(i)) {
							break;
						}
						ps.addBatch();
					}
					return ps.executeBatch();
				}
				else {
					List<Integer> rowsAffected = new ArrayList<>();
					for (int i = 0; i < batchSize; i++) {
						pss.setValues(ps, i);
						if (ipss != null && ipss.isBatchExhausted(i)) {
							break;
						}
						rowsAffected.add(ps.executeUpdate());
					}
					int[] rowsAffectedArray = new int[rowsAffected.size()];
					for (int i = 0; i < rowsAffectedArray.length; i++) {
						rowsAffectedArray[i] = rowsAffected.get(i);
					}
					return rowsAffectedArray;
				}
			}
			finally {
				if (pss instanceof ParameterDisposer) {
					((ParameterDisposer) pss).cleanupParameters();
				}
			}
		});

		Assert.state(result != null, "No result array");
		return result;
	

3. 使用方法

public int batchInsert(List<TblStockOrderItemBarcode> tblStockOrderItemBarcodes, JdbcTemplate jdbcTemplate) {
        String insertStockOrderItemBarcodeSql = "INSERT INTO tblStockOrderItemBarcode (lStockOrderItemID, lVoucherTypeID, lVoucherNumber, Stock_strBarcode, Stock_strPIN) " +
                "VALUES (?, ?, ?, ?, ?)";
        int[] updateCountArray = jdbcTemplate.batchUpdate(insertStockOrderItemBarcodeSql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setInt(1, tblStockOrderItemBarcodes.get(i).getLstockorderitemid());
                ps.setInt(2, tblStockOrderItemBarcodes.get(i).getLvouchertypeid());
                ps.setInt(3, tblStockOrderItemBarcodes.get(i).getLvouchernumber());
                ps.setString(4, tblStockOrderItemBarcodes.get(i).getStockStrbarcode());
                ps.setString(5, tblStockOrderItemBarcodes.get(i).getStockStrpin());
            }
            @Override
            public int getBatchSize() {
                return tblStockOrderItemBarcodes.size();
            }
        });
        int sumInsertedCount = 0;
        for (int a : updateCountArray) {
            sumInsertedCount += a;
        }
        return sumInsertedCount;
    }

三.使用提供的SQL语句和提供的参数列表执行批处理

1.接口API源码

int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException;

2.接口API源码实现

@Override
	public int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException {
		return batchUpdate(sql, batchArgs, new int[0]);
	}

	@Override
	public int[] batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes) throws DataAccessException {
		if (batchArgs.isEmpty()) {
			return new int[0];
		}

		return batchUpdate(
				sql,
				new BatchPreparedStatementSetter() {
					@Override
					public void setValues(PreparedStatement ps, int i) throws SQLException {
						Object[] values = batchArgs.get(i);
						int colIndex = 0;
						for (Object value : values) {
							colIndex++;
							if (value instanceof SqlParameterValue) {
								SqlParameterValue paramValue = (SqlParameterValue) value;
								StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue());
							}
							else {
								int colType;
								if (argTypes.length < colIndex) {
									colType = SqlTypeValue.TYPE_UNKNOWN;
								}
								else {
									colType = argTypes[colIndex - 1];
								}
								StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value);
							}
						}
					}
					@Override
					public int getBatchSize() {
						return batchArgs.size();
					}
				});
	}

 3. 使用方法

public int batchUpdate(List<TblStock> tblStocks, JdbcTemplate jdbcTemplate) {
        String insertStockSql = "INSERT INTO tblStock (lVoucherTypeID, lVoucherNumber, nDuplicateNo, lStockLocationID, " +
                "lIssuedLocationID VALUES (?, ?, ?, ?, ?)";
        List<Object[]> batchArgs = tblStocks.stream().map(tblStock -> {
            return new Object[]{tblStock.getLvouchertypeid(), tblStock.getLvouchernumber(), tblStock.getNduplicateno(),
                    tblStock.getLstocklocationid(), tblStock.getLissuedlocationid()};
        }).collect(Collectors.toList());
        int[] updateCountArray = jdbcTemplate.batchUpdate(insertStockSql, batchArgs);
        return updateCountArray.length;
    }

四.使用提供的SQL语句和提供的参数集合执行多个批处理

1. 接口API源码

<T> int[][] batchUpdate(String sql, Collection<T> batchArgs, int batchSize,
      ParameterizedPreparedStatementSetter<T> pss) throws DataAccessException;

2. 接口API源码实现

public <T> int[][] batchUpdate(String sql, final Collection<T> batchArgs, final int batchSize,
			final ParameterizedPreparedStatementSetter<T> pss) throws DataAccessException {

		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL batch update [" + sql + "] with a batch size of " + batchSize);
		}
		int[][] result = execute(sql, (PreparedStatementCallback<int[][]>) ps -> {
			List<int[]> rowsAffected = new ArrayList<>();
			try {
				boolean batchSupported = JdbcUtils.supportsBatchUpdates(ps.getConnection());
				int n = 0;
				for (T obj : batchArgs) {
					pss.setValues(ps, obj);
					n++;
					if (batchSupported) {
						ps.addBatch();
						if (n % batchSize == 0 || n == batchArgs.size()) {
							if (logger.isTraceEnabled()) {
								int batchIdx = (n % batchSize == 0) ? n / batchSize : (n / batchSize) + 1;
								int items = n - ((n % batchSize == 0) ? n / batchSize - 1 : (n / batchSize)) * batchSize;
								logger.trace("Sending SQL batch update #" + batchIdx + " with " + items + " items");
							}
							rowsAffected.add(ps.executeBatch());
						}
					}
					else {
						int i = ps.executeUpdate();
						rowsAffected.add(new int[] {i});
					}
				}
				int[][] result1 = new int[rowsAffected.size()][];
				for (int i = 0; i < result1.length; i++) {
					result1[i] = rowsAffected.get(i);
				}
				return result1;
			}
			finally {
				if (pss instanceof ParameterDisposer) {
					((ParameterDisposer) pss).cleanupParameters();
				}
			}
		});

		Assert.state(result != null, "No result array");
		return result;
	}

3. 使用方法

public int batchUpdate(List<TblStock> tblStocks, JdbcTemplate jdbcTemplate) {
        String insertStockSql = "INSERT INTO tblStock (lVoucherTypeID, lVoucherNumber, nDuplicateNo, lStockLocationID, " +
                "lIssuedLocationID VALUES (?, ?, ?, ?, ?)";
        List<Object[]> batchArgs = tblStocks.stream().map(tblStock -> {
            return new Object[]{tblStock.getLvouchertypeid(), tblStock.getLvouchernumber(), tblStock.getNduplicateno(),
                    tblStock.getLstocklocationid(), tblStock.getLissuedlocationid()};
        }).collect(Collectors.toList());
        int[] updateCountArray = jdbcTemplate.batchUpdate(insertStockSql, batchArgs);
        return updateCountArray.length;
    }

3. 使用方法

public int batchInsert(List<TblStock> tblStocks, JdbcTemplate jdbcTemplate) {
        String insertStockSql = "INSERT INTO tblStock (lVoucherTypeID, lVoucherNumber, nDuplicateNo, lStockLocationID, lIssuedLocationID VALUES (?, ?, ?, ?, ?)";

        int[][] batchResult = jdbcTemplate.batchUpdate(insertStockSql, tblStocks, 100, ((ps, argument) -> {
            ps.setInt(1, argument.getLvouchertypeid());
            ps.setInt(2, argument.getLvouchernumber());
            ps.setByte(3, argument.getNduplicateno());
            ps.setInt(4, argument.getLstocklocationid());
            ps.setInt(5, argument.getLissuedlocationid());
        }));
        int sumInsertedCount = 0;
        for(int i = 0; i < batchResult.length; i++) {
            for(int j = 0; j < batchResult[0].length; j++) {
                sumInsertedCount += batchResult[i][j];
            }
        }
        return sumInsertedCount;
    }

 

 

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JdbcTemplate是Spring框架中的一个核心类,用于简化JDBC操作。它提供了方便的方法来执行SQL查询、更新和批处理操作。 在使用JdbcTemplate之前,需要先获取JdbcTemplate对象。根据提供的引用内容,有三种常见的方式可以获取JdbcTemplate对象。 第一种方式是通过在Spring配置文件中定义一个JdbcTemplate的bean,并将其注入到需要使用的类中。在提供的代码示例中,可以看到在Spring配置文件中定义了一个名为"jdbcTemplate"的bean,并将其注入到了UserServiceImpl类中的setJdbcTemplate方法中。这样,UserServiceImpl类就可以通过调用getJdbcTemplate方法来获取JdbcTemplate对象。 第二种方式是直接在需要使用JdbcTemplate的类中定义一个JdbcTemplate的成员变量,并提供相应的setter方法。在提供的代码示例中,可以看到在UserServiceImpl类中定义了一个名为"jdbcTemplate"的成员变量,并提供了setJdbcTemplate方法来注入JdbcTemplate对象。这样,UserServiceImpl类就可以通过调用getJdbcTemplate方法来获取JdbcTemplate对象。 第三种方式是通过编程方式创建JdbcTemplate对象,然后进行相应的配置。这种方式相对较少使用,一般在没有Spring配置文件的情况下使用。通过创建JdbcTemplate对象并手动设置它的数据源,可以实现与数据库的连接。具体代码示例如下: ```java DataSource dataSource = ...; // 创建数据源 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // 创建JdbcTemplate对象 ``` 需要注意的是,无论通过哪种方式获取JdbcTemplate对象,都需要先配置好数据源,以便JdbcTemplate能够正确地与数据库进行连接。 总结起来,要使用JdbcTemplate,可以通过在Spring配置文件中定义一个JdbcTemplate的bean并注入到需要使用的类中,或者在需要使用JdbcTemplate的类中直接定义一个JdbcTemplate的成员变量并提供相应的setter方法。另外,还可以通过编程方式创建JdbcTemplate对象并手动设置数据源。无论哪种方式,都需要确保已正确配置数据源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值