zoukankan      html  css  js  c++  java
  • JDBC的PreparedStatement语句使用记录

    <<JDBC为什么要使用PreparedStatement而不是Statement>> 列举了为什么PreparedStatement要优于Statement,其中最主要的两点是更快的性能和防止SQL注入攻击。在文章的末尾提到了一个局限性:PreparedStatement不允许一个占位符(?)有多个值,并提出了如何在**IN**子句使用PreparedStatement的棘手问题。

    《JDBC PreparedStatement IN clause alternative approaches》 给出了四种方案:

    1. Execute Single Queries

    2. Using Stored Procedure

    3. Creating PreparedStatement Query dynamically

    4. Using NULL in PreparedStatement Query

    第三和第四方案看起来更合适些,第四种方案可以看作是第三种方案的扩展。

    第三种使用下面代码构建SQL语句

    private static String createQuery(int length) {
            String query = "select empid, name from Employee where empid in (";
            StringBuilder queryBuilder = new StringBuilder(query);
            for( int i = 0; i< length; i++){
                queryBuilder.append(" ?");
                if(i != length -1) queryBuilder.append(",");
            }
            queryBuilder.append(")");
            return queryBuilder.toString();
        }

    这种方式虽然可行,但是如果输入的参数个数发生变化,就不会get the PreparedStatement benefit of caching and reusing the execution plan。

    所以就有了第四种方案:

    public class JDBCPreparedStatementNULL {
     
        private static final String QUERY = "select empid, name from Employee where empid in ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        private static final int PARAM_SIZE = 10;
        public static void printData(int[] ids){
             
            if(ids.length > PARAM_SIZE){
                System.out.println("Maximum input size supported is "+PARAM_SIZE);
                //in real life, we can write logic to execute in batches, for simplicity I am returning
                return;
            }
            Connection con = DBConnection.getConnection();
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                ps = con.prepareStatement(QUERY);
                 
                int i = 1;
                for(; i <=ids.length; i++){
                    ps.setInt(i, ids[i-1]);
                }
                 
                //set null for remaining ones
                for(; i<=PARAM_SIZE;i++){
                    ps.setNull(i, java.sql.Types.INTEGER);
                }
                 
                rs = ps.executeQuery();
                     
                while(rs.next()){
                    System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));
                }
                     
                //close the resultset here
                try{
                    rs.close();
                } catch(SQLException e){}
                 
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                try {
                    ps.close();
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    在第三种方案的基础上,我们确定最大参数个数,除了输入的参数外,剩余参数全部用setNull()置为空。这样又可以重用执行计划和预处理的cache。

    More:PreparedStatement and Statement可以批量执行,参考《使用JDBC进行批处理》

  • 相关阅读:
    FCKEditor装入模板方法
    医道再解开阖枢
    测试一下 Last
    [技术架构] 大型互联网站解决高并发的常见策略
    swfupload实现图片及缩略图上传
    解决“在证书存储区中找不到清单签名证书”
    asp.net EnableViewState禁用与注意事项
    jQuery创建水平和垂直居中的div窗口
    甩掉ashx/asmx,使用jQuery.ajaxWebService请求WebMethod,Ajax处理更加简练
    type="button" ,"submit" 的区别(转)
  • 原文地址:https://www.cnblogs.com/wangyinhui/p/4123144.html
Copyright © 2011-2022 走看看