PreparedStatement与Statement对比、sql语句的被注入问题

来源:互联网 发布:数据挖掘工具分类 编辑:程序博客网 时间:2024/05/02 04:51

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)首先引入这样一个概念: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);        }    }}

运行结果:

推荐使用PreparedStatement

1 0
原创粉丝点击