jdbc之批处理
来源:互联网 发布:盐城大数据产业园官网 编辑:程序博客网 时间:2024/06/08 03:36
批操作可以一次性向数据库端发送若干SQL语句,从而减少与数据库服务端的网络通信,提高执行效率。
当大批量执行SQL语句时,影响效率的三个因素:
1:事务,事务越多速度越慢(事务最好一次提交);
2:网络调用,网络调用越多速度越慢(这里可以使用缓存解决);
3:Statement,PreparedStatement的选用,因为执行计划越多效率越慢。
关于第三点,做过测试,选用PrepareStatement效率明显比Statement高,因为用它只生成一次执行计划,后面传参使用同一个计划。就好像java程序中定义方法,动态信息被定义为参数,多次调用方法传入不同参数即可,但是方法不用每次都重新定义。
关于第一点,可以不让事务自动提交(默认事务是自动提交的,比如prepareStatement.executeUpdate()执行后事务就是自动提交了的,关于事务的问题也讲过,这样在出现异常事务却提交了,没有保证一致性,有时候会存在很大问题),最后事务一次提交。
关于第三点,使用缓存解决,添加一个批操作,将很多sql语句缓存在本地,最后语句一次性发送给数据库服务端,这样做可以有效的减少网络调用次数,提高与数据库服务端的通讯效率。
需求:向数据库中userinfo表插入10000条数据
自动提交事务,不添加缓存测试:
public class JDBCBatch { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { connection = DBUtil.getConnection(); statement = connection.createStatement(); long start =new Date().getTime(); System.out.println("开始前:"+start); for (int i = 0; i < 10000; i++) { String sql="INSERT INTO userinfo " + "VALUES " + "(seq_userinfo_id.NEXTVAL,'test"+i+"','123456'," + "5000,'test"+i+"@tedu.cn')"; //立刻将SQL发送至数据库服务端 statement.executeUpdate(sql); } System.out.println("结束用时:"+(new Date().getTime()-start)); } catch (Exception e) { }finally { DBUtil.closeConnection(); } }}
输出:开始前:1502871180710结束用时:10757
使用以上给出的解决方案:
public class JDBCDemo2 { public static void main(String[] args) { Connection connection = null; PreparedStatement pStatement; try { connection = DBUtil.getConnection(); connection.setAutoCommit(false); String sql="INSERT INTO userinfo " + "VALUES " + "(seq_userinfo_id.NEXTVAL,?,'123456',5000" + ",?)"; pStatement = connection.prepareStatement(sql); long time = new Date().getTime(); for (int i = 0; i < 10000; i++) { pStatement.setString(1, "aa"+i); pStatement.setString(2, "scu@qq.com"+i); pStatement.addBatch(); } pStatement.executeBatch(); System.out.println("用时:"+(new Date().getTime() - time)); //清空本地缓存 pStatement.clearBatch(); connection.commit(); } catch (Exception e) { try { connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { DBUtil.closeConnection(); } }}
输出:用时:103
结果:
一个用时10757ms一个用时103ms,效率得到了极大的提高。
注:虽然说应该用控制变量法,但是为了方便就一起测了,自己可以分别测试。三种方案都能提供效率。
Api:connection.setAutoCommit(false):事务自动提交关闭connection.commit():提交事务connection.rollback():回滚事务pStatement.addBatch():添加批操作(相对于缓存至本地)pStatement.executeBatch():执行批操作pStatement.clearBatch():清空本地缓存
DBUtil是个自己封装的工具类,能获取和关闭连接
public class DBUtil { private static String driver; private static String url; private static String username; private static String password; private static String maxactive; private static String maxwait; //数据库连接池 private static BasicDataSource dateSource; private static ThreadLocal<Connection> tl; static{ try { tl = new ThreadLocal<>(); //加载配置文件 Properties properties = new Properties(); properties.load(new FileInputStream(new File("D:\\测试\\jdbc\\src\\config.properties"))); //读取配置文件,初始化成员变量 driver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); maxactive = properties.getProperty("maxactive"); maxwait = properties.getProperty("maxwait"); //测试初始化是否成功 System.out.println(driver); System.out.println(url); System.out.println(username); System.out.println(password); System.out.println(maxactive); System.out.println(maxwait); dateSource = new BasicDataSource(); dateSource.setDriverClassName(driver); dateSource.setUrl(url); dateSource.setUsername(username); dateSource.setPassword(password); dateSource.setMaxActive(new Integer(maxactive)); dateSource.setMaxWait(new Integer(maxwait)); } catch (Exception e) { //静态方法块里面是不能抛出异常的 e.printStackTrace(); } } /* * 从连接池获取数据库连接 */ public static Connection getConnection() throws Exception{ Connection connection = dateSource.getConnection(); tl.set(connection); return connection; } public static void closeConnection(){ Connection conn=tl.get(); if(conn!=null){ try { //这个时候用的是连接池的close,其他方法是oracle的, //连接池只是起了代理的做用 conn.close(); tl.remove(); } catch (SQLException e) { e.printStackTrace(); } } } /* * 关闭连接 */ public static void closeConnection(Connection connection,Statement statement,ResultSet resultSet){ if(resultSet != null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement != null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }}
阅读全文
0 0
- jdbc之批处理
- JDBC之批处理数据
- jdbc之批处理
- JDBC进阶之批处理 Batch
- JavaWeb学习心得之JDBC批处理
- JDBC之批处理、事务、存储过程
- 04.JDBC编程之指定变量&批处理
- jdbc学习总结五之批处理
- JDBC批处理
- jdbc批处理
- JDBC批处理
- JDBC批处理
- jdbc批处理
- JDBC批处理
- JDBC批处理
- JDBC批处理
- jdbc 批处理
- JDBC批处理
- http range header
- Dubbo 回调用服务的处理逻辑
- 对于堆栈的疑问
- Alluxio 1.5.0开源发布版的技术亮点
- hdu_5104_素数表的应用
- jdbc之批处理
- 对于ie8和ie8一下版本不支持placeholder(文本框提示信息)的解决方案
- Windows PowerShell 2.0之服务管理
- 工作中的坑-----javabean属性命名
- UI自动化体系建设的创新实践
- 最后的战犯
- 九度1026:又一版A+B
- spring boot 使用thymeleaf 和shiro标签整合
- Oracle迁移Linux到Windows,版本从低到高