批处理可以将多个SQL语句一次性发送给数据库,可以减少连接数据库的开销。

JDBC实现批处理有两种方式:Statement和PreparedStatement

一、使用Statement对象进行批处理操作

步骤:

①使用createStatement()方法创建Statement对象

②使用setAutoCommit()将auto-commit设置为false。(这是JDBC的自动提交,默认是true,即开启自动提交)

③使用addBatch()方法在创建的语句对象上添加SQL语句到批处理中

④在创建的语句上使用executeBatch()方法执行所有SQL语句

⑤使用commit()方法提交所有改动

先准备一个数据库students:

CREATE TABLE `students` (
  `sid` varchar(8) NOT NULL,
  `sname` varchar(255) DEFAULT NULL,
  `gender` varchar(255) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

db2 批量导入 insert db2批量commit_bc

下面使用代码来展示:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class StatementBatch {
	public static void main(String[] args) {
		Connection conn = null;
		Statement st = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql:///test","root", "1234");
			//创建Statement对象
			st = conn.createStatement();
			//设置自动提交为false
			conn.setAutoCommit(false);
			//SQL语句
			String sql1 = "insert into students values('S0000004','赵六','女','2015-10-12','银川')";
			String sql2 = "insert into students values('S0000005','小明','男','2016-10-12','呼和浩特')";
			String sql3 = "insert into students values('S0000006','小红','女','2017-10-12','喀什')";
			st.addBatch(sql1);
			st.addBatch(sql2);
			st.addBatch(sql3);
			int[] array = st.executeBatch();
			conn.commit();
			if(array.length>0){
				System.out.println("添加成功!");
			}else{
				System.out.println("添加失败!");
			}
			for (int i : array) {
				System.out.println(i);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(st != null){
					st.close();
				}
				if(conn != null){
					conn.close();
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

db2 批量导入 insert db2批量commit_sql_02

db2 批量导入 insert db2批量commit_db2 批量导入 insert_03

注意我们在代码中定义的array,批量添加返回的是一个数组,成功一条返回一个1,失败一条返回一个0。

使用Statement.addBatch(sql)方式实现批处理:

优点:可以向数据库发送多条不同的SQL语句

缺点:SQL语句没有预编译,当发送多条语句相同,但仅参数不同的SQL语句的时候,需要重复写多条SQL语句。

二、使用PrepareStatement对象进行批处理

步骤:

①使用占位符创建SQL语句

②使用PrepareStatement()方法创建PrepareStatement对象

③使用setAutoCommit()将auto-commit设置为false

④使用addBatch()方法在创建的语句对象上添加SQL语句到批处理中

⑤在创建的语句对象上使用executeBatch()方法执行所有SQL语句

⑥使用commit()方法提交所有改动

下面是代码展示:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class PreparedStatementBatch {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection("jdbc:mysql:///test","root", "1234");
			String sql = "insert into students values(?,?,?,?,?)";
			ps = conn.prepareStatement(sql);
			
			conn.setAutoCommit(false);
			ps.setString(1, "S0000007");
			ps.setString(2, "李雷");
			ps.setString(3, "女");
			ps.setString(4, "1980-01-01");
			ps.setString(5, "拉萨");
			ps.addBatch();
			ps.setString(1, "S0000008");
			ps.setString(2, "韩梅梅");
			ps.setString(3, "男");
			ps.setString(4, "1980-12-31");
			ps.setString(5, "鸡西");
			
			ps.addBatch();
			
			int[] array = ps.executeBatch();
			
			conn.commit();
			if(array.length>0){
				System.out.println("添加成功!");
			}else{
				System.out.println("添加失败!");
			}
			for (int i : array) {
				System.out.println(i);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(ps != null){
					ps.close();
				}
				if(conn != null){
					conn.close();
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

db2 批量导入 insert db2批量commit_SQL_04

db2 批量导入 insert db2批量commit_db2 批量导入 insert_05

还可以进行对象批处理,这里给出一个实例代码:

@Test
	public void t1(){
		
		List<Employees> list=new ArrayList<Employees>();
		list.add(new Employees(206, "tom1", "123", 123));
		list.add(new Employees(207, "tom2", "123", 123));
		list.add(new Employees(208, "tom3", "123", 123));
		list.add(new Employees(209, "tom4", "123", 123));
		list.add(new Employees(210, "tom5", "123", 123));
		list.add(new Employees(211, "tom6", "123", 123));
		list.add(new Employees(212, "tom7", "123", 123));
		
		Connection conn=JdbcUtils.openConn();
		try {
			conn.setAutoCommit(false); //关闭自动提交
			String sql="INSERT INTO Employees (id, first, last, age) VALUES(?,?,?,?)";
			PreparedStatement ps = conn.prepareStatement(sql);
			
			for (Employees e : list) {
				ps.setObject(1, e.getId());
				ps.setObject(2, e.getFirst());
				ps.setObject(3, e.getLast());
				ps.setObject(4, e.getAge());
				ps.addBatch();
			}
			int[] arrays = ps.executeBatch(); //执行批处理
			conn.commit(); //手动提交
			System.out.println("执行完毕:"+Arrays.toString(arrays));
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

三、处理二进制数据

PreparedStatement对象可以使用输入和输出流来提供参数数据。可以将整个文件放入可以保存大值的数据库列,例如BLOB数据类型

数据库表:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `image` longblob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这里只展示代码,不做结果及演示:

存储

public static void main(String[] args) throws Exception {
		Connection conn = null;
		PreparedStatement st=null;
		
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection("jdbc:mysql://192.168.132.128:3306/employeesdb?useUnicode=true&characterEncoding=utf-8", "root", "123");
		
		String sql = "insert into testblob(image) values(?)";
		st = conn.prepareStatement(sql);
		
		File file = new File("D:\\005.jpg");
        FileInputStream fis = new FileInputStream(file);//生成的流
        
        st.setBinaryStream(1, fis,(int) file.length());
        
        int num = st.executeUpdate();
        if(num>0){
            System.out.println("插入成功!!");
        }
        fis.close();
	}

读取:

public static void main(String[] args) throws Exception {
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs=null;

		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection("jdbc:mysql://192.168.132.128:3306/employeesdb?useUnicode=true&characterEncoding=utf-8", "root", "123");

		String sql = "select image from testblob where id=?";
		st = conn.prepareStatement(sql);
		st.setInt(1, 1);
		rs = st.executeQuery();
		if (rs.next()) {
			// InputStream in = rs.getBlob("image").getBinaryStream();//这种方法也可以
			InputStream in = rs.getBinaryStream("image");
			int len = 0;
			byte buffer[] = new byte[1024];

			FileOutputStream out = new FileOutputStream("D:\\1.jpg");
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
			in.close();
			out.close();
		}
	}