浅析PreparedStatement

PreparedStatement作为Statement的增强版,提供更好的可读性和维护性。通过预编译技术,其执行效率高于Statement,尤其适合多次执行相同SQL的情况。此外,预编译还能防止SQL注入,确保数据安全。了解PreparedStatement的工作原理,如预编译过程,有助于优化数据库操作。

PreparedStatement继承自Statement,但比Statement功能强大的多。

具体可从三个方面来分析:

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

stmt.executeUpdate("insert into tb_name 
    (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')"); 

perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) 
    values (?,?,?,?)"); 
    perstmt.setString(1,var1); 
    perstmt.setString(2,var2); 
    perstmt.setString(3,var3); 
    perstmt.setString(4,var4); 
    perstmt.executeUpdate(); 

 

2、预编译
     PreparedStatement是使用带占位符参数(预编译语法)来编写Sql语句的
     Statement是直接执行静态Sql语句

     这样的话PreparedStatement的执行效率会更高,当使用同一个PreparedStatement对象执行多次时,
     只需要编译一次。
     当同时要执行多条相同结构sql语句时使用,这时可以用setObject()addBatch()executeBatch()
     
这几个函数。

package com;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestPreparedStatement {
    public static void main(String[] args) {
        Connection con = null;
        PreparedStatement pst = null;
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

            String url = "jdbc:sqlserver://127.0.0.1:1433;databaseName=userManager";
            con = DriverManager.getConnection(url, "as", "");
           

            String sql = "insert into myuser (userName,pwd) values (? , ?)";
            pst = con.prepareStatement(sql);
           

            pst.setString(1, "张三");  //也可以用setObject()
            pst.setString(2, "123");
            pst.addBatch();
   
            pst.setString(1, "李四");
            pst.setString(2, "456");
            pst.addBatch();
   
            pst.executeBatch();
   
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
           try {
               if (pst != null) {
                   pst.close();
                   pst = null;
               }
               if (con != null) {
                   con.close();
                   con = null;
               }
           } catch (SQLException e) {
               e.printStackTrace();
           }
       }
    }
}


拓展:

预编译也就预处理,叫什么都行。它就是把SQL语句的模板生成一个函数,模板中的“?”就是函数的参数。当给“?”赋值之后,再执行SQL语句时,就是用参数来调用函数。

例如:SELECT * FROM tab_student WHERE s_number=?,这是一条SQL模板语句,当使用这个SQL模板获取PreparedStatement对象时,已经把这条SQL模板发送给了SQL服务器,这时SQL服务器会根据SQL模板生成一个函数一样的东西:详情讲看

functioin myfun(?) {

   …

}

当使用PreparedStatement为“?”设置了值后(pstmt.setString(1,”S_1001”),再去调用executeQuery()方法时,就是在使用参数调用函数一样:myfun(“S_1001”)。

 

3、防sql注入
      由于PreparedStatement是预编译过的,所以当用户输入非法参数时,会进行特殊处理以防止Sql注入

打印出执行Sql为:

Statement对象就没那么好心了,它才不会把用户非法输入的单引号用\反斜杠做转义!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值