目录

一、批量插入数据

⚪JDBC的批量处理语句的方法

二、高效的批量插入

1.举例:向goods表中插入20000条数据

⭐goods表的创建

方式一:使用Statement

方式二: 使用PreparedStatement替换Statement

🌙方式一与方式二的对比

方式三: 相关方法的调用

方式四: 设置连接不允许自动提交数据


一、批量插入数据

  • PreparedStatement可以实现更高效的批量操作
  • update、delete本身就具有批量操作的效果
  • 此时的批量操作,主要指的是批量插入。使用PreparedStatement如何实现更高效的批量插入?

当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处 理。通常情况下比单独提交处理更有效率

⚪JDBC的批量处理语句的方法

  • addBatch(String):添加需要批量处理的SQL语句或是参数;
  • executeBatch():执行批量处理语句;
  • clearBatch():清空缓存的数据

二、高效的批量插入

1.举例:向goods表中插入20000条数据

⭐goods表的创建

CREATE TABLE goods(
  id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(25)
);

方式一:使用Statement

public class InsertTest {
    //方式一:使用Statement
    @Test
    public void test1() throws Exception {
        Connection conn = JDBCUtils.getConnection();
        Statement st = conn.createStatement();
        for (int i = 1; i < 20000; i++) {
            String sql = "insert into goods (name) values ('name_" + i + "')";
            st.execute(sql);
        }
    }
}

方式二: 使用PreparedStatement替换Statement

@Test
public void test2() {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        long start = System.currentTimeMillis();
        conn = JDBCUtils.getConnection();
        String sql = "insert into goods (name) values (?)";
        ps = conn.prepareStatement(sql);
        for (int i = 1; i <= 20000; i++) {
            ps.setObject(1,"name_" + i); //填充占位符
            ps.execute();
        }
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:" +(end - start));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCUtils.closeResource(conn,ps);
    }
}

  

🌙方式一与方式二的对比

PreparedStatement 能最大可能提高性能:

  • DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的 编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行
  • 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意 义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。

  • (语法检查,语义检查,翻译成二进制命令,缓存)

PreparedStatement 可以防止 SQL 注入

方式三: 相关方法的调用

  • mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。&rewriteBatchedStatements=true 写在配置文件的url后面
  • 使用更新的mysql 驱动:mysql-connector-java-5.1.37-bin.jar  
    @Test
    public void test3() {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            long start = System.currentTimeMillis();
            conn = JDBCUtils.getConnection();
            String sql = "insert into goods (name) values (?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= 20000; i++) {
                ps.setObject(1, "name_" + i); //填充占位符
                //1."攒"sql
                ps.addBatch();
                if (i % 500 == 0){
                    //2.执行Batch
                    ps.executeBatch();

                    //3.清空Batch
                    ps.clearBatch();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("花费的时间为:" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(conn, ps);
        }
    }

时间变化:33899  ———>  2243 

方式四: 设置连接不允许自动提交数据

@Test
public void test4() {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        long start = System.currentTimeMillis();
        conn = JDBCUtils.getConnection();
        //设置不允许自动提交数据
        conn.setAutoCommit(false);
        String sql = "insert into goods (name) values (?)";
        ps = conn.prepareStatement(sql);
        for (int i = 1; i <= 20000; i++) {
            ps.setObject(1, "name_" + i); //填充占位符
            //1."攒"sql
            ps.addBatch();
            if (i % 500 == 0){
                //2.执行Batch
                ps.executeBatch();
                //3.清空Batch
                ps.clearBatch();
            }
        }
        //统一提交数据
        conn.commit();
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:" + (end - start));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCUtils.closeResource(conn, ps);
    }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐