JDBC进阶之批处理 Batch

本文介绍了JDBC中的批处理机制,通过一次性执行多条SQL语句提高数据库操作性能。批处理允许在某条语句出错时仍继续执行其他语句,区别于事务处理。文章详细讲解了利用JDBC实现批处理的步骤,并提供了一个示例代码,演示了从创建Connection到执行批处理的完整流程。
摘要由CSDN通过智能技术生成

          批处理,英文叫 Batch,顾名思义就是成批地处理某些事务。对于频繁访问数据库的程序而言,选择批处理是最合适不过的了。本文将介绍如何利用 JDBC 实现批处理。


一、什么是批处理

          屁处理是指一次性执行多条SQL语句,并且在执行过程中,如果某条语句出现错误,则仅停止该错误语句的执行,而批处理中其他所有语句则继续执行。这是有别与事务处理 (事务处理的详情参见《JDBC进阶之事务处理基本原理及示例》) 的,事务处理一旦出现错误,则全部都取消执行并进行回滚。

          JDBC API 中提供了批处理的机制,可以让 Statement 同时执行多个 SQL 语句,以提高操作数据库的性能。


二、利用JDBC 实现批处理的基本步骤

          1)创建 Connection 对象,利用 Connection 对象创建 Statement 对象;

          2)判断是否支持批处理;

          3)取消 Connection 对象的自动提交模式;

          4)使用 Statement 对象的增加批处理语句的 addBatch() 方法;

          5)使用 Statement 对象执行批处理的 executeBatch() 方法批处理执行多条添加到 Statement 对象中的 SQL 语句;

          6)关闭连接;


三、批处理应用示例

          根据上述的基本概念和使用方法,接下来通过一个具体的实例来体会上述知识,加深理解。根据利用 JDBC 实现批处理的基本步骤,接下来的示例中对应上述每个步骤的代码片段分解如下:

           1)利用 JDBC 连接数据库,并创建 Connection 对象。这个问题在之前的几篇文章都在重复,不明白之处可前去参考《JDBC连接MySQL数据库及示例》。代码片段如下:


  
  
Connection con = DriverManager.getConnection( "jdbc:mysql://localhost:3306/myuser", "root", "root");
Statement sm = con.createStatement();

           2)判断当前使用的JDBC驱动程序和数据库是否批处理。代码片段如下:

DatabaseMetaData md = con.getMetaData();// 得到数据库的元数据			
return md.supportsBatchUpdates();	//获取此数据库是否支持批量更新,并返回结果,支持则为true	


           3)取消 Connection 对象的自动提交模式;代码片段如下:

con.setAutoCommit(false);	// 设置连接不自动提交,即用该连接进行的操作都不更新到数据库

            4)通过addBatch() 方法添加虚批处理的信息;代码片段如下:

sm.addBatch(sqls[i]); // 将所有的SQL语句添加到Statement中


           5)通过executeBatch() 方法执行批处理,并且提交事务;代码片段如下:

int[] batchResultList = sm.executeBatch(); // 将一批命令提交给数据库来执行,并返回更新计数组成的数组。
con.commit();	//提交事务


           6)关闭连接;代码片段如下:

sm.close();
con.close(); 

完整代码如下:

package chp07;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Batch_Executable {
	// 利用 JDBC 连接数据库
	public static Connection getConnection() { 
		Connection con = null;
		try {
			Class.forName("com.mysql.jdbc.Driver"); // 加载Mysql数据驱动
			con = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/myuser", "root", "root"); // 创建数据连接
		} catch (Exception e) {
			System.out.println("数据库连接失败");
		}
		return con;
	}
	
	// 判断当前使用的JDBC驱动程序和数据库是否支持事务处理
	public static boolean isBatch(Connection con) {
		try {
			DatabaseMetaData md = con.getMetaData();// 得到数据库的元数据			
			return md.supportsBatchUpdates();	//获取此数据库是否支持批量更新,并返回结果,支持则为true		
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

	// 执行一批SQL语句
	public static int[] startBatch(Connection con, String[] sqls)
			throws Exception {
		if (sqls == null) {
			return null;
		}
		Statement sm = null;
		try {
			con.setAutoCommit(false);	// 设置连接不自动提交,即用该连接进行的操作都不更新到数据库
			sm = con.createStatement();
			for (int i = 0; i < sqls.length; i++) {
				sm.addBatch(sqls[i]); // 将所有的SQL语句添加到Statement中
			}
			int[] batchResultList = sm.executeBatch(); // 将一批命令提交给数据库来执行,并返回更新计数组成的数组。
			con.commit();	//提交事务
			
			return batchResultList;	//返回更新计数组成的数组。
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			sm.close();
		}
		return null;
	}

	public static void main(String[] args) throws Exception {
		String[] arry = new String[3];// 定义一组事物处理语句
		arry[0] = "delete from staff where name='Serein'";
		arry[1] = "UPDATE staff SET address='Shenzhen' where name='lili'";// 执行这条语句会引起错误,因为表student中name='lili'不存在
		arry[2] = "INSERT INTO staff (name,age,sex,address,depart,worklen,wage) \n"
				+ "values ('Serein',39,'M','Beijing','Accountant',6,8800)"; //插入一条员工记录
		Connection con = null;
		try {
			con = getConnection(); // 获得数据库连接
			boolean Batch_Flag = isBatch(con); // 判断是否支持批处理
			System.out.print("数据库是否支持批量更新? :" + Batch_Flag);
			System.out.println(Batch_Flag ? " 支持" : " 不支持");
			if (Batch_Flag) {
				int[] results = startBatch(con, arry); // 执行一批SQL语句
				// 分析执行的结果
				for (int i = 0; i < arry.length; i++) {
					if (results[i] >= 0) {
						System.out.println("语句: " + arry[i] + " 执行成功,影响了" + results[i] + "行数据\n");
					} else if (results[i] == Statement.SUCCESS_NO_INFO) {
						System.out.println("语句: " + arry[i] + " 执行成功,影响的行数未知\n");
					} else if (results[i] == Statement.EXECUTE_FAILED) {
						System.out.println("语句: " + arry[i] + " 执行失败\n");
					}
				}
			}
		} catch (ClassNotFoundException e1) {
			throw e1;
		} catch (SQLException e2) {
			throw e2;
		} finally {
			con.close(); // 关闭数据库连接
		}
		System.out.println("执行批处理后的数据为:");
		query();
	}
	
	// 查询所有的数据
	public static void query() throws Exception { 
		Connection con = getConnection();
		Statement st = con.createStatement();
		ResultSet rs = st.executeQuery("select * from staff");
		while (rs.next()) { // 判断是否还有下一个数据
			// 根据字段名获取相应的值
			int ID = rs.getInt("ID");	//ID字段
			String name = charset(rs.getString("name"));	//name字段
			int age = rs.getInt("age");		//age字段
			String sex = charset(rs.getString("sex"));
			String depart = charset(rs.getString("depart"));	//depart字段
			String address = charset(rs.getString("address"));	//address字段
			int worklen = rs.getInt("worklen");		//worklen字段
			int wage = rs.getInt("wage");		//wage字段
			System.out.println(ID + " "  + name + " " + age + " " + sex + " "
					+ address + " " + depart + " " + worklen + " " + wage);
		}
	}
	
	// 字符集的设定为UTF-8
	public static String charset(String str) throws Exception {
		String newStr = new String(str.getBytes("ISO8859-1"), "UTF-8");
		return newStr;
	}

}

说明:该Java程序中数据库操作涉及的数据库为 “myuser ” ,并使用其中的 “staff” 表格,也就是我之前的文章《JDBC连接MySQL数据库及示例》里所创建的数据库和表。如果需要跟着去实现并运行这个例子的话,可以前去参考创建,或者根据你自己的数据库情况去修改其中有关连接MySQL的代码以及SQL语句。

附上程序运行前的“staff”表格中的数据:观察其中紫色圈起来的“Serein”这条记录,并与下面程序运行后的结果图对比。

Java 程序运行结果如下图所示:




如果觉得写的还好,顺手一下哦 ^ ^







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值