JDBC大批量写入数据到SQLServer2000,记录数大于10000

本文介绍了一种使用Java进行数据库批量插入的方法,通过控制每1000条数据执行一次批处理来提高插入效率,并记录了整个过程所用的时间。
		SpObserver.putSp("sessionFactory1"); 
		SimpleDateFormat fomat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Session s=null;
		s=daoSupport.getSessionFactory().openSession();
		Connection con=s.connection();
		Statement stmt = null;
		try {
			stmt=con.createStatement();
			con.setAutoCommit(false);
			Iterator it=list.iterator();
			int iCount = 1;
			long start = System.currentTimeMillis();
			while(it.hasNext()){
				TResultWaterZId t = (TResultWaterZId)it.next();
				StringBuffer sb = new StringBuffer();
				sb.append("insert into T_result_water_z(schemeid,stcd,z,tm) values('");
				sb.append(t.getSchemeid()).append("','").append(t.getStcd()).append("','");
				sb.append(t.getZ()).append("','").append(fomat.format(t.getTm())).append("')");
				stmt.addBatch(sb.toString());
				if(iCount % 1000 == 0){
					stmt.executeBatch();
					stmt.clearBatch();
				}
				iCount++;
			}
			stmt.executeBatch();
			stmt.clearBatch();
			con.commit();
			long end = System.currentTimeMillis();
			System.out.println("addTResultWaterZId used time:"+(end-start));
			stmt.close();
			con.close();
		} catch (SQLException e) {
			try {
				con.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try {
				stmt.close();
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

转载于:https://www.cnblogs.com/qumao5736/archive/2009/12/07/1618547.html

### Java 批量插入数据库并确保完成 为了确保大批量数据在Java中被成功保存到MySQL数据库之后才执行下一个操作,可以采用多种策略和技术手段。以下是几种常见的方式: #### 使用 `PreparedStatement` 的批量更新功能 通过使用JDBC提供的`addBatch()` 和 `executeBatch()` 方法可以在单次网络往返中处理多个SQL命令,从而显著提高性能。 ```java Connection conn = null; PreparedStatement pstmt = null; try { String sql = "INSERT INTO table_name (column1, column2) VALUES (?, ?)"; conn = DriverManager.getConnection(url, user, password); conn.setAutoCommit(false); // 关闭自动提交模式 pstmt = conn.prepareStatement(sql); for (int i = 0; i < largeDataSet.size(); ++i) { Object dataPoint = largeDataSet.get(i); pstmt.setString(1, ((DataObject)dataPoint).getColumn1Value()); pstmt.setInt(2, ((DataObject)dataPoint).getColumn2Value()); pstmt.addBatch(); if (i % batchSize == 0 || i == largeDataSet.size()-1){ pstmt.executeBatch(); conn.commit(); // 提交当前批次的数据 } } } catch (SQLException e) { try { if(conn != null && !conn.isClosed()) conn.rollback(); // 发生异常时回滚事务 } catch(SQLException ex) {} throw new RuntimeException(e.getMessage(),e); } finally{ //关闭资源... } ``` 此代码片段展示了如何利用预编译语句(`PreparedStatement`)来进行高效的批量插入,并且只有当所有的记录都被正确写入后才会确认更改[^1]。 #### MyBatis Plus 配置优化 对于MyBatis Plus框架而言,默认情况下即使调用了`saveBatch()`方法也可能会逐条发送insert语句给数据库服务器。为了避免这种情况发生,应该调整数据库连接字符串以启用真正的批量加载特性: ```properties jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true ``` 上述URL参数中的`rewriteBatchedStatements=true`选项会指示驱动程序尝试重写多行插入为更有效的形式[^2]。 #### 利用线程池管理并发任务 虽然增加并发度可以帮助加速整体进程,但如果控制不当也可能引发新的问题比如死锁或资源争用。因此建议合理规划工作单元的数量以及它们之间的同步机制。一种做法是在每个子任务完成后通知主线程直到全部结束为止;另一种则是依靠高级别的抽象类如`CountDownLatch` 或者 `CompletableFuture`. ```java ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); CountDownLatch latch = new CountDownLatch(totalTasks); for(int i=0;i<totalTasks;++i){ final int taskIndex=i; executor.submit(() -> { try{ performInsertionForTask(taskIndex,batchOfDataPerThread); } finally { latch.countDown(); } }); } latch.await(); // 主线程等待所有子线程完成 executor.shutdownNow(); // 继续下一步骤... private void performInsertionForTask(int taskId,List<Data> batch){ // 实现具体的插入逻辑 } ``` 这段伪代码说明了怎样创建固定数量的工作线程去分担总的任务负载,并让主流程暂停直至收到每一个工作者的通知表明其已经完成了分配给自己那部分工作的信号[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值