addBatch()用法(jdbc事务控制)

本文介绍如何使用PreparedStatement的addBatch()方法进行批量SQL操作,包括连接数据库、预编译SQL语句及执行批处理等步骤,并提供了一个完整的Java示例。
addBatch()用法
查看文章
PreparedStatement.addbatch()的使用
Statement和PreparedStatement的区别就不多废话了,直接说PreparedStatement最重要的addbatch()结构的使用.

1.建立链接
Connection connection =getConnection();

2.不自动 Commit
connection.setAutoCommit(false);

3.预编译SQL语句,只编译一回哦,效率高啊
PreparedStatement statement = connection.prepareStatement("INSERT INTO TABLEX VALUES(?, ?)");

//记录1
statement.setInt(1, 1);
statement.setString(2, "Cujo");
statement.addBatch();

//记录2
statement.setInt(1, 2);
statement.setString(2, "Fred");
statement.addBatch();

//记录3
statement.setInt(1, 3);
statement.setString(2, "Mark");
statement.addBatch();

//批量执行上面3条语句.
int [] counts = statement.executeBatch();

//Commit it 到(DB)里面


**

已安装了microsoft 驱动程序

jdk1.4; win2000 server; MS sql2000;

*/

import java.sql.*;


class sql
{

public static void main(String[] agrs)
{
Connection cn=null;
Statement stmt=null;
String sql=null;

try
{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
}
catch(ClassNotFoundException ex)
{
System.out.println("Not find the Driver!");
}

try
{
String urls="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=webroot";//webroot 库名.TALBE 是表名;
String user="sa";
String password="password";
cn= DriverManager.getConnection(urls,user,password);

//stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
stmt=cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

sql="select top 10 * from TABLE1";
ResultSet rs= stmt.executeQuery(sql);
while(rs.next())
{
System.out.println(rs.getString(2)+" "+rs.getString(3));

}

rs.first();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 1 "+rs.getString(3));

rs.last();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 2 "+rs.getString(3));

rs.previous();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 3 "+rs.getString(3));

rs.next();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 4 "+rs.getString(3));

rs.absolute(2);
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" 5 "+rs.getString(3));

/*
rs.afterLast();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" "+rs.getString(3));
System.out.print(rs.isAfterLast());

rs.beforeFirst();
System.out.print(rs.getRow()+" ");
System.out.println(rs.getString(2)+" "+rs.getString(3));
*/

String sql1="update TABLE1 set 题目=? where id=? ";
PreparedStatement stmt1 = cn.prepareStatement(sql1);
String stat = new String("盛夏话足部保健");
String stat1 = UnicodeToGB(stat);//解决中文问题
stmt1.setString(1,stat1);
stmt1.setInt(2,3423);
stmt1.executeUpdate();
cn.commit();

//System.out.println(stat1);
//System.exit(0);

//cn.setAutoCommit(false);

stmt.addBatch("update TABLE1 set 题目="盛夏话足部保健1" where id="3407"");
stmt.addBatch("update TABLE1 set 题目="夏季预防中暑膳食1" where id="3408"");
stmt.addBatch("INSERT INTO TABLE1 VALUES("11","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("12","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("13","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("14","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("15","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("16","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("17","12","13","","")");
stmt.addBatch("INSERT INTO TABLE1 VALUES("18","12","13","","")");

int [] updateCounts=stmt.executeBatch();
cn.commit();



stmt.close();
cn.close();
}
catch(SQLException e)
{
System.out.println("The SQLException error!");
}

}
/*
*/

public static String UnicodeToGB(String strIn){
byte[] b;
String strOut = null;
if(strIn == null || (strIn.trim()).equals(""))
return strIn;
try{
b = strIn.getBytes("GBK");
strOut = new String(b,"ISO8859_1");
}
catch(Exception e){
System.out.println("unicodeToGB exception : " + e.getMessage() + "\n");
}
return strOut;
}
/*
*/
}
### JDBC 批量插入时未调用 `clearBatch` 的影响及正确用法JDBC 批量操作中,`addBatch()` 方法用于将 SQL 语句添加到批处理队列中,而 `executeBatch()` 方法则用于执行这些批量的 SQL 语句。`clearBatch()` 方法的作用是清空当前批处理队列中的所有 SQL 语句[^1]。如果在使用 `addBatch()` 后未调用 `clearBatch()`,可能会产生以下影响: #### 1. 内存占用问题 如果未调用 `clearBatch()`,批处理队列中的 SQL 语句将一直保留,直到下一次调用 `executeBatch()` 或连接关闭。这可能导致内存占用逐渐增加,尤其是在循环中反复调用 `addBatch()` 但未清理的情况下[^3]。例如,在一个大规模的数据插入场景中,如果不清理批处理队列,程序可能因内存不足而崩溃。 #### 2. 数据一致性问题 在事务管理中,如果未调用 `clearBatch()`,可能会导致批处理队列中的 SQL 语句在事务提交后仍然存在,从而引发不必要的重复执行或数据不一致问题[^4]。例如,当事务回滚后,批处理队列中的 SQL 语句并未被清除,下次执行时可能会重新插入相同的数据。 #### 3. 性能下降 未调用 `clearBatch()` 可能导致批处理队列中积累过多的 SQL 语句,从而降低性能。每次调用 `executeBatch()` 时,数据库需要处理整个批处理队列中的所有语句,如果队列过大,执行时间会显著增加[^3]。 --- ### 正确用法 为了确保批处理操作的高效性和安全性,应遵循以下正确用法: #### 1. 在适当的时间点调用 `executeBatch()` 在批量插入时,应在适当的间隔调用 `executeBatch()` 来执行批处理队列中的 SQL 语句。例如,可以每 1000 条记录执行一次批量操作,以平衡内存占用和性能[^3]。 ```java for (int i = 1; i <= 10000; i++) { stat.addBatch("insert into stu values(" + i + ",'张三',25,'男');"); if (i % 1000 == 0) { int[] result = stat.executeBatch(); System.out.println("Executed batch: " + result.length); stat.clearBatch(); // 清理批处理队列 } } ``` #### 2. 调用 `clearBatch()` 清理批处理队列 在每次调用 `executeBatch()` 后,建议立即调用 `clearBatch()` 来清空批处理队列。这样可以避免内存泄漏和不必要的重复执行[^1]。 #### 3. 管理事务提交 在批量插入时,通常需要手动管理事务。可以通过设置 `conn.setAutoCommit(false)` 来禁用自动提交,并在所有 SQL 语句加载完毕后调用 `conn.commit()` 提交事务[^4]。 ```java Connection conn = DbUtils.getConnection(); try { conn.setAutoCommit(false); // 禁用自动提交 PreparedStatement pstmt = conn.prepareStatement("INSERT INTO stu (id, name, age, gender) VALUES (?, ?, ?, ?)"); for (int i = 1; i <= 10000; i++) { pstmt.setInt(1, i); pstmt.setString(2, "张三"); pstmt.setInt(3, 25); pstmt.setString(4, "男"); pstmt.addBatch(); if (i % 1000 == 0) { pstmt.executeBatch(); pstmt.clearBatch(); } } pstmt.executeBatch(); // 执行剩余的批处理 conn.commit(); // 提交事务 } catch (SQLException e) { conn.rollback(); // 回滚事务 e.printStackTrace(); } finally { conn.close(); } ``` --- ### 注意事项 - **SQL 注入问题**:在使用 `addBatch()` 时,如果直接拼接 SQL 字符串,可能会导致 SQL 注入风险。建议使用 `PreparedStatement` 来绑定参数,从而避免此类问题[^1]。 - **异常处理**:在执行批处理时,应捕获可能的异常并进行适当的处理,例如回滚事务或记录错误日志[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值