PreparedStatement和Statement

来源:互联网 发布:python pyqt5 安装 编辑:程序博客网 时间:2024/06/14 13:18

转自:http://blog.csdn.net/qq_34944851/article/details/53454385

PreparedStatement vs Statment 

一、语法不同:PreparedStatement可以使用预编译的sql,而Statement只能使用静态的sql。

二、效率不同: PreparedStatement可以使用sql缓存区,效率比Statement高。 

三、安全性不同: PreparedStatement可以有效防止sql注入,而Statement不能防止sql注入。 
通过案例对比来给大家讲解这一点: 
1、Statement模拟用户登陆:

package sram.login;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.Statement;import org.junit.Test;import sram.util.jdbc.JdbcUtil;/** * 模拟用户登录效果 */public class Demo1 {    //模拟用户输入    private String name = "zhangsan";    private String password = "123";    @Test    public void testByStatement(){        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;        try {            //获取连接            conn = JdbcUtil.getConnection();            //创建Statment            stmt = conn.createStatement();            //准备sql            //注意带参的sql语句的书写            String sql = "SELECT * FROM admin WHERE userName='"+name+"' AND pwd='"+password+"'";            System.out.println(sql);            //执行sql            rs = stmt.executeQuery(sql);            if(rs.next()){                //登录成功                System.out.println("登录成功");            }else{                System.out.println("登录失败");            }        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException(e);        } finally {            JdbcUtil.close(conn, stmt,rs);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

乍一看没什么问题啊,可以识别用户,判断是否登陆成功,但是接下来给大家介绍这样的一个情况: 
1)首先引入这样一个概念:sql语句被注入 
 
2)接下来我们稍稍修改下刚才的代码: 
 
3)而PreparedStatement接口则不存在这种问题。

2、PreparedStatement模拟用户登陆:

package sram.login;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.Statement;import org.junit.Test;import sram.util.jdbc.JdbcUtil;/** * 模拟用户登录效果 */public class Demo1{    //模拟用户输入:SELECT * FROM admin WHERE userName='zhangsan' OR 1=1 -- 'AND pwd='123';    private String name = "用户随意输入' OR 1=1 -- ";    private String password = "密码任意";    /**     * Statment存在sql被注入的风险     */    //public void testByStatement(){}    /**     * PreparedStatement可以有效地防止sql被注入     */    @Test    public void testByPreparedStatement(){        Connection conn = null;        PreparedStatement stmt = null;        ResultSet rs = null;        try {            //获取连接            conn = JdbcUtil.getConnection();            String sql = "SELECT * FROM admin WHERE userName=? AND pwd=?";            //预编译            stmt = conn.prepareStatement(sql);            //设置参数            stmt.setString(1, name);            stmt.setString(2, password);            //执行sql            rs = stmt.executeQuery();            if(rs.next()){                //登录成功                System.out.println("登录成功");            }else{                System.out.println("登录失败");            }            System.out.println(sql);            System.out.println(stmt);            System.out.println(rs);        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException(e);        } finally {            JdbcUtil.close(conn, stmt ,rs);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

运行结果: 

推荐使用PreparedStatement