PreparedStatement的用法

本文探讨了在Java开发中使用PreparedStatement替代Statement的重要性。通过预编译SQL语句,不仅提高了代码的可读性和可维护性,还显著提升了应用程序性能,并增强了安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个PreparedStatement是从java.sql.connection对象和所提供的sql字符串得到的,sql字符串中包含问号(?),这些问号标明变量的位置,然后提供变量的,最后执行语句,例如:

String sql = "select id,name from student where id=? andname=?";

PreparedStatement ps =conn.prepareStatement(sql);
ps.setint(1,id);
ps.setstring(2,name);
ResultSet rs = ps.executeQuery();
在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.除非只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement。

基于以下的原因:
一.代码的可读性和可维护性.

虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:


二.PreparedStatement尽最大可能提高性能

每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.

当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.


三.最重要的一点是极大地提高了安全性

编写SQL语句,尤其是要插入多个Filed时,是一件非常麻烦的事情,  使用PreparedStatement可以使代码变得更优雅一些,虽然会有些长, 但会更条理, 而且PreparedStatement更高于SQL语句 - 相对来说不太容易随着数据库版本改变而变动. 另外preparedstatement效率更高,安全性更好

一个完整的实例

import java.sql.*;

public class TestPreStmt {

 
 public static void main(String[] args) {
  ResultSet rs = null;
  Connection conn = null;
  PreparedStatement pst =null;
    try {
      //第一步:加载MySQL的JDBC的驱动
        Class.forName("com.mysql.jdbc.Driver"); 
       //取得连接的url,能访问MySQL数据库的用户名,密码;数据库名
         String url = "jdbc:mysql://localhost:3306/2";
         String user = "root";
         String password = "19870714";
       //第二步:创建与MySQL数据库的连接类的实例
         conn = DriverManager.getConnection(url, user, password);
       //第三步:用conn创建Statement对象类实例 stmt
          String sql = "select id,name fromstudent where id=? andname=?";
         pst =conn.prepareStatement(sql);   
          pst.setInt(1, 1);
         pst.setString(2,"张三");
         rs=pst.executeQuery();
         while(rs.next()){
          System.out.println(rs.getString("id"));
          System.out.println(rs.getString("name"));
         }
         
        String ps = "insert into studentvalues(?,?,?)"; 
        pst = conn.prepareStatement(ps);
        pst.setInt(1, 5);
        pst.setString(2, "pig");
        pst.setString(3, "m");
        pst.executeUpdate();
    } catch (ClassNotFoundException e){  
    //加载JDBC错误,所要用的驱动没有找到
     System.out.println("驱动加载错误");
  }catch (SQLException ex){
   //显示数据库连接错误或查询错误
    System.err.println("SQLException:"+ex.getMessage());
  }finally {
    try{
      
        if(pst != null) {
         pst.close();
         pst = null;
        }
        if(conn != null) {
         conn.close();
         conn = null;
        }
    }catch(SQLException e) {
    System.err.println("SQLException:"+e.getMessage());
    }
  }
 }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值