05、批量插入
5.1、批量执行SQL语句
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。
JDBC
的批量处理语句包括下面三个方法:
addBatch(String)
:添加需要批量处理的SQL
语句或是参数;executeBatch()
:执行批量处理语句;clearBatch()
:清空缓存的数据。
通常我们会遇到两种批量执行SQL
语句的情况:
- 多条SQL语句的批量处理;
- 一个SQL语句的批量传参;
5.2、高效的批量插入
题目:向goods
表中插入20000条数据
- 数据库提供一个
goods
表。创建如下:
CREATE TABLE goods(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(25)
);
5.2.1、实现一:使用Statement
//方式一:使用Statement
Connection con = JDBCUtil.getConnection();
Statement sm = con.createStatement();
for(int i = 1; i <= 20000; i++) {
String sql = "insert into goods(name) values ('name_ "+ i +"')";
sm.execute(sql);
}
5.2.2、实现二:使用PreparedStatement
/**
* 使用PreparedStatement实现批量数据的操作
*
* update、delete本身就具有批量操作的效果
* 此时的批量操作,主要是指批量插入,使用PreparedStatement如何实现更高效的批量插入?
*/
public class InsertTest {
//批量插入的方式二,使用PreparedStatement
@Test
public void testInsert() {
Connection con = null;
PreparedStatement psm = null;
try {
con = JDBCUtil.getConnection();
long start = System.currentTimeMillis();
String sql = "insert into goods(name) values (?)";
psm = con.prepareStatement(sql);
for (int i = 1; i <= 20000; i++) {
psm.setObject(1, "name_"+i);
psm.execute();
}
long end = System.currentTimeMillis();
System.out.println("花费的时间:" + (end - start));//花费的时间:23294
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.closeResource(con, psm);
}
}
}
5.2.3、实现三
-
清空数据库
TRUNCATE TABLE goods;
-
使用驱动:
mysql-connector-java-5.1.37-bin.jar
项目名 --> 右击,选择Open Module Settings --> 选择Project Settings下的Libraries
-
使用
batch
的相关方法package jdbcTest.blob; import jdbcTest.JDBCUtil; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; public class InsertTest { /** * 批量插入的方式三: * 1.addBatch()、executeBatch()、clearBatch() * 2.mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。 * ?rewriteBatchedStatements=true 写在配置文件的url后面 * 3.使用更新的mysql 驱动:mysql-connector-java-5.1.37-bin.jar */ @Test public void testInsert3() { Connection con = null; PreparedStatement psm = null; try { con = JDBCUtil.getConnection(); long start = System.currentTimeMillis(); String sql = "insert into goods(name) values (?)"; psm = con.prepareStatement(sql); for (int i = 1; i <= 20000; i++) { psm.setObject(1, "name_"+i); //1."攒sql" psm.addBatch(); if (i % 500 == 0) { //2.执行batch psm.executeBatch(); //3.清空batch psm.clearBatch(); } } long end = System.currentTimeMillis(); System.out.println("花费的时间:" + (end - start));//20000花费的时间:248 //1000000话费的时间:5421 } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, psm); } } }
5.2.4、实现四
package jdbcTest.blob;
import jdbcTest.JDBCUtil;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class InsertTest {
/**
* 批量插入的方式四:
*/
@Test
public void testInsert4() {
Connection con = null;
PreparedStatement psm = null;
try {
long start = System.currentTimeMillis();
con = JDBCUtil.getConnection();
//设置不允许自动提交数据
con.setAutoCommit(false);
String sql = "insert into goods(name) values (?)";
psm = con.prepareStatement(sql);
for (int i = 1; i <= 1000000; i++) {
psm.setObject(1, "name_"+i);
//1."攒sql"
psm.addBatch();
if (i % 500 == 0) {
//2.执行batch
psm.executeBatch();
//3.清空batch
psm.clearBatch();
}
}
//提交数据
con.commit();
long end = System.currentTimeMillis();
System.out.println("花费的时间:" + (end - start));//花费的时间:2820
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.closeResource(con, psm);
}
}
}