zoukankan      html  css  js  c++  java
  • JDBC_批量处理语句提高处理速度

    •当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
    •JDBC的批量处理语句包括下面两个方法:
    –addBatch(String):添加需要批量处理的SQL语句或是参数;
    –executeBatch();执行批量处理语句;
    •通常我们会遇到两种批量执行SQL语句的情况:
    –多条SQL语句的批量处理;
    –一个SQL语句的批量传参;
    批量处理有二种方法一种是Statment和PreparedStatemnet:

    Statement  

    •通过调用 Connection 对象的 createStatement 方法创建该对象
    •该对象用于执行静态的 SQL 语句,并且返回执行结果
    •Statement接口中定义了下列方法用于执行 SQL 语句:
    –ResultSet excuteQuery(String sql)
    –int excuteUpdate(String sql)
    /**
    	 * 向 mysql 的 customers 数据表中插入 10 万条记录 测试如何插入, 
    	 * 用时最短. 1. 使用 Statement.
    	 */
    	@Test
    	public void testBatchWithStatement() {
    		Connection connection = null;
    		Statement statement = null;
    		String sql = null;
    
    		try {
    			connection = JDBCTools.getConnection();
    			JDBCTools.beginTx(connection);
    
    			statement = connection.createStatement();
    
    			long begin = System.currentTimeMillis();
    			for (int i = 0; i < 100000; i++) {
    				sql = "INSERT INTO customerss VALUES(" + (i + 1) + ", 'name_"
    						+ i + "', '2015-05-15')";
    				statement.addBatch(sql);
    			}
    			long end = System.currentTimeMillis();
    
    			System.out.println("Time: " + (end - begin)); 
    
    			JDBCTools.commit(connection);
    		} catch (Exception e) {
    			e.printStackTrace();
    			JDBCTools.rollback(connection);
    		} finally {
    			JDBCTools.releaseDB(null, statement, connection);
    		}
    	}
    


    PreparedStatement

    •可以通过调用 Connection 对象的 preparedStatement() 方法获取PreparedStatement 对象
    •PreparedStatement 接口是 Statement的子接口,它表示一条预编译过的 SQL 语句
    •PreparedStatement 对象所代表的 SQL语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的SQL 语句中的参数的值
    /**
    	 * 向 mysql 的 customers 数据表中插入 10 万条记录 测试如何插入, 
    	 * 用时最短. 1. 使用 PreparedStatement.
    	 */
    	@Test
    	public void testBatchWithPreparedStatement() {
    		Connection connection = null;
    		PreparedStatement preparedStatement = null;
    		String sql = null;
    
    		try {
    			connection = JDBCTools.getConnection();
    			JDBCTools.beginTx(connection);
    			sql = "INSERT INTO customerss VALUES(?,?,?)";
    			preparedStatement = connection.prepareStatement(sql);
    			Date date = new Date(new java.util.Date().getTime());
    
    			long begin = System.currentTimeMillis();
    			for (int i = 0; i < 100000; i++) {
    				preparedStatement.setInt(1, i + 1);
    				preparedStatement.setString(2, "name_" + i);
    				preparedStatement.setDate(3, date);
    
    				preparedStatement.executeUpdate();
    			}
    			long end = System.currentTimeMillis();
    
    			System.out.println("Time: " + (end - begin)); 
    
    			JDBCTools.commit(connection);
    		} catch (Exception e) {
    			e.printStackTrace();
    			JDBCTools.rollback(connection);
    		} finally {
    			JDBCTools.releaseDB(null, preparedStatement, connection);
    		}
    	}

    PreparedStatement vs Statement

    •代码的可读性和可维护性.
    •PreparedStatement 能最大可能提高性能:
    –DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。
    –在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次. 
    –(语法检查,语义检查,翻译成二进制命令,缓存)
    •PreparedStatement 可以防止 SQL注入 
    /**
     * 使用batch增强
     */
    	@Test
    	public void testBatch() {
    		Connection connection = null;
    		PreparedStatement preparedStatement = null;
    		String sql = null;
    		try {
    			connection = JDBCTools.getConnection();
    			JDBCTools.beginTx(connection);
    			sql = "INSERT INTO customerss VALUES(?,?,?)";
    			preparedStatement = connection.prepareStatement(sql);
    			Date date = new Date(new java.util.Date().getTime());
    			long begin = System.currentTimeMillis();
    			for (int i = 0; i < 100000; i++) {
    				preparedStatement.setInt(1, i + 1);
    				preparedStatement.setString(2, "name_" + i);
    				preparedStatement.setDate(3, date);
    				// 积攒SQL语句
    				preparedStatement.addBatch();
    				// 当积攒到一定程度,就统一的执行一次,并清空先前积攒的SQL
    				if ((i + 1) % 300 == 0) {
    					preparedStatement.executeBatch();
    					preparedStatement.clearBatch();
    				}
    			}
    			// 若总条数不是批量数值的整数倍,则还需要额外的执行一次
    			if (100000 % 300 != 0) {
    				preparedStatement.executeBatch();
    				preparedStatement.clearBatch();
    			}
    			long end = System.currentTimeMillis();
    
    			System.out.println("Time: " + (end - begin)); // 9819
    
    			JDBCTools.commit(connection);
    		} catch (Exception e) {
    			e.printStackTrace();
    			JDBCTools.rollback(connection);
    		} finally {
    			JDBCTools.releaseDB(null, preparedStatement, connection);
    		}
    	}

  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/Rollins/p/4524887.html
Copyright © 2011-2022 走看看