Statement及PreparedStatement执行多个sql

Posted C# java C++ 开源通信

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Statement及PreparedStatement执行多个sql相关的知识,希望对你有一定的参考价值。

    这两个对象的区别:
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()方法数据库记录:

技术图片

数据库数据记录表明: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语句时,可以减少通信开销,从而提高性能。

 

 

 

以上是关于Statement及PreparedStatement执行多个sql的主要内容,如果未能解决你的问题,请参考以下文章

JDBC-PreparedStatement实现CURD(笔记)

Statement及PreparedStatement执行多个sql

2.mysql binlog的三种格式及区别

JDBC中Statement和PrepareStatement的区别及特性

[Js-JDBC]SQL注入及解决,Statement与PreparedStatement

cannot insert multiple commands into a prepared statement问题原因及解决办法