• 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);
    		}
    	}

  • 相关阅读:
    月半小夜曲下的畅想--DOCTYPE模式
    css模块化思想(一)--------命名是个技术活
    聊聊css盒子模型
    【随笔】借鉴 & KPI式设计
    【转载】社交的蒸发冷却效应
    【随笔】写在闪电孵化器分享会之后
    【随笔】微信删除加载动画
    【随笔】微信支付有感 续
    【转载】如何把产品做简单
    【随笔】写在2014年的第一天
  • 原文地址:https://www.cnblogs.com/Rollins/p/4524887.html
Copyright © 2020-2023  润新知