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进行批处理》

时间: 2024-10-26 12:44:38

JDBC的PreparedStatement语句使用记录的相关文章

jdbc操作数据库语句

非常有用的jdbc操作数据库语句,记录下来,以方便以后的查询. public class PersonDao { // 增加操作 public void insert(Person person) throws Exception; // 修改操作 public void update(Person person) throws Exception; // 删除操作 public void delete(String id) throws Exception ; // 按ID查询操作 publi

02.lomboz与JDBC处理DDL语句应用举例

一.lomboz开发工具 Lomboz是Eclipse的一个主要的开源插件(open-source plug-in),Lomboz插件能够使Java开发者更好的使用Eclipse去创建,调试和部署一个100%基于J2EE的Java应用服务器. Lomboz插件的使用,使得Eclipse将多种J2EE的元素.Web应用的开发和最流行的应用服务器车结合为一体.用它来替换myeclipse是没有任何问题的,这里我们只需用来开发JDBC数据库应用程序. 1.下载及安装  lomboz的官方网站,http

JDBC中PreparedStatement接口提供的execute、executeQuery和executeUpdate之间的区别及用法

JDBC中PreparedStatement接口提供的execute.executeQuery和executeUpdate之间的区别及用法 (2012-08-27 09:36:18) 转载▼ 标签: statement execute executequery executeupdate 杂谈 分类: DataBase区 PreparedStatement接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语

JDBC操作SQL语句的注释和拼接

上网浏览帖子发现一个关于SQL中的in里面的参数动态添加的问题. 通常in里面的参数通过一个子查询获得与该参数相同类型或者可互转换的类型的一个字段信息.实际中经常会用到有个数组,该数组的内容正好是作为in里面的参数列表.通过SQL拼接的方式一定能够实现,即便看起来比较繁琐. 下面是通过预编译命令和参数占位的方式来实现: String sql = "select urlid, url from f_url where url in(?)";         pstmt = conn.pr

JDBC Statements, PreparedStatement和CallableStatement语句

当获得了与数据库的连接后,就可以与数据库进行交互了. JDBC Statement,CallableStatement和PreparedStatement接口定义了可用于发送SQL或PL/SQL命令,并从数据库接收数据的方法和属性. 它们还定义了有助于在Java和SQL数据类型的数据类型差异转换的方法.下表提供了每个接口定义,以及使用这些接口的目的的总结. 接口 推荐使用 Statement 用于对数据库进行通用访问,在运行时使用静态SQL语句时很有用. Statement接口不能接受参数. P

JDBC批处理Select语句

注:为了更好理解本文,请结合原文阅读 在上一篇文章中提到了PreparedStatement的局限性:PreparedStatement不允许一个占位符(?)设置多个值,本文试图从其它角度来解决该问题. 在网络上开销最昂贵的资源就是客户端与服务器往返的请求与响应,JDBC中类似的一种情况就是对数据库的调用,如果你在做数据插入.更新.删除操作,可以使用executeBatch()方法减少数据库调用次数,如: 1 2 3 4 5 Statement pstmt = conn.createStatem

通过jdbc使用PreparedStatement,提升性能,防止sql注入

为什么要使用PreparedStatement? 一.通过PreparedStatement提升性能 Statement主要用于执行静态SQL语句,即内容固定不变的SQL语句.Statement每执行一次都要对传入的SQL语句编译一次,效率较差.     某些情况下,SQL语句只是其中的参数有所不同,其余子句完全相同,适用于PreparedStatement.PreparedStatement的另外一个好处就是预防sql注入攻击     PreparedStatement是接口,继承自State

JDBC预编译语句表名占位异常

有时候,我们有这样的需求,需要清空多个表的内容,这样我们有两种做法,可用delete from table 或 truncate table table,两种方法视情况而定,前者只是一条条的删除表数据,主键自增的序列还能保存,后者类似是重新建表保留表结构,主键信息,也被清空. OK,下面我们用JDBC开始删除,因为是多个表,所以要循环删除,根据以往的经验,使用预编译的sql语句,可能执行效率会更高,短短几行代码,搞定: public void clearTables()throws Except

JDBC Statement PreparedStatement CallableStatement

在 JDBC 应用程序中,JDBC 语句对象用于将 SQL 语句发送到数据库服务器.一个语句对象与一个连接相关联,应用程序与数据库服务器之间的通信由语句对象来处理. JDBC 中有三种类型的语句对象: 1. 常规语句(General statement) 2. 预置语句(Prepared statement) 3. 可调用语句(Callable statement) 语句对象与一个连接相关联,所以要创建一个语句对象,首先应该建立一个数据库连接.连接的获取见上一篇博客. 关于这三种语句,个人觉得最