Statement及PreparedStatement执行多个sql

时间:2022-01-26 07:32:48

    这两个对象的区别: 1.Statement它更适合执行不同sql的批处理,它没有提供预处理功能,性能比较低。 2.PreparedStatement它适合执行相同的批处理,它提供了预处理功能,属性比较高。            /**       *  @param args       *  @throws SQLException       *  @throws ClassNotFoundException       */       public  static  void main(String[] args)  throws ClassNotFoundException,                 SQLException {             // 定义sql 语句            String sql1 = "create table person(id int,name varchar(20))";            String sql2 = "insert into person values(1,‘tom‘)";            String sql3 = "insert into person values(2,‘fox‘)";            String sql4 = "insert into person values(3,‘tony‘)";            String sql5 = "update person set name=‘张三‘ where id=1";            String sql6 = "delete from person where id=3";              Connection conn = jdbcUtils. getConnection();            Statement st = conn.createStatement();               // 添加批处理sql            st.addBatch(sql1);            st.addBatch(sql2);            st.addBatch(sql3);            st.addBatch(sql4);            st.addBatch(sql5);            st.addBatch(sql6);               // 执行批处理sql            st.executeBatch();            st.clearBatch();            st.close();             conn.close();        }     使用版本高一点的 jdbc的jar包时加入参数可开启缓存在url中加参数: ?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true      /**       *  @param args       *  @throws SQLException       *  @throws ClassNotFoundException       */       public  static  void main(String[] args)  throws ClassNotFoundException,                 SQLException {            String sqlString = "insert into person values(?,?)";            Connection conn = jdbcUtils.  getConnection();            PreparedStatement pst = conn.prepareStatement(sqlString);              long l = System.  currentTimeMillis();              for (  int i = 0; i < 10000; i ) {                 pst.setInt(1, i);                 pst.setString(2, "name"  i);                 pst.addBatch();                   if (i % 1000 == 0) {                      pst.executeBatch();                      pst.clearBatch(); // 清空缓存                 }            }            pst.executeBatch();            pst.close();            conn.close();            System.  out.println(System.  currentTimeMillis() - l);      }    

方法:

  1.   public static Connection getConnection(){
  2.   try {
  3.   Class.forName( "com.mysql.jdbc.Driver");
  4.   ct = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/test","squirrel","xiaoyang");
  5.   } catch (Exception e) {
  6.   e.printStackTrace();
  7.   }
  8.   return ct;
  9.   }
  10.    
  11.   /**释放数据库链接资源:注意数据库资源关闭的顺序*/
  12.   public static void closeConnection(){
  13.    
  14.   try { //注意关闭数据库资源的先后顺序
  15.   if(rs!=null){
  16.   rs.close();
  17.   } if(ps!=null){
  18.   ps.close();
  19.   } if(ct!=null){
  20.   ct.close();
  21.   }
  22.   } catch (SQLException e) {
  23.   e.printStackTrace();
  24.   }
  25.   }
  26.    

测试方法:

  1.   /**
  2.   * PreparedStatement批量执行sql
  3.   */
  4.   public static void excuteBatchInsertDatabase(){
  5.    
  6.   ct=getConnection();
  7.    
  8.   try {
  9.   ct.setAutoCommit( false);
  10.   ps=ct.prepareStatement( "insert into user(name,passwd,age,gender) values(?,?,?,?)");
  11.    
  12.   ps.setString( 1, "BBBB");
  13.   ps.setString( 2, "BBBB");
  14.   ps.setInt( 3, 20);
  15.   ps.setString( 4, "F");
  16.   ps.addBatch();
  17.    
  18.   ps.setString( 1, "BBBB");
  19.   ps.setString( 2, "BBBB");
  20.   ps.setInt( 3, 20);
  21.   ps.setString( 4, "F");
  22.   ps.addBatch();
  23.    
  24.   /**
  25.   * 等价于sql语句:
  26.   * insert into user(name,passwd,age,gender) values
  27.   * ("BBBB","BBBB",20,‘F‘),
  28.   * ("BBBB","BBBB",20,‘F‘);
  29.   */
  30.   ps.executeBatch(); //批量执行sql,避免因此单次的insert操作建立多个Connection浪费资源
  31.   ct.commit();
  32.   } catch (Exception e) {
  33.   e.printStackTrace();
  34.   try {
  35.   ct.rollback();
  36.   } catch (SQLException e1) {
  37.   e1.printStackTrace();
  38.   }
  39.   } finally{
  40.   closeConnection();
  41.   }
  42.   }

执行excuteBatchInsertDatabase()方法数据库记录:

Statement及PreparedStatement执行多个sql

数据库数据记录表明:sql语句批量执行成功

注意:

批量查询最好交由一个事务组控制,如果出现操作异常可以进行事务回滚,不至于造成部分数据更新部分数据更新失败的尴尬局面,避免你脏数据污染数据库

 

  • 由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率
  • Statement用于执行静态的sql语句
  • 由于PreparedStatement创建对象消耗资源比较高,所以只执行 一次的sql语句,不使用PreparedStatement

  • 主要目的减少执行计划次数,防止sql注入
  • jdbc 元数据 meta  ,ResultSet.xxx
  • Mysql jdbc 关闭自动提交事务 可提升性能 conn.setAutoCommit(false) ,
  • 归还conn时 须提前设置为.setAutoCommit(true)
  • rollback()回滚 
  • 批量处理:一次向数据库发送多个SQL语句时,可以减少通信开销,从而提高性能。