JavaWeb学习十五(PreparedStatement)

一.PreparedStatement概述

  • 它是Statement接口的子接口
  • 强大之处:
    • 防SQL攻击
    • 提高代码的可读性,可维护性
    • 提高效率

1.什么是SQL攻击

在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们DAO中写的
SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语句的片段!

2.演示SQL攻击

 public boolean login(String username,String password) throws ClassNotFoundException, SQLException {
              Class.forName("com.mysql.jdbc.Driver");

               String user="root";
               String pass="T471912619";
               String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";
               Connection connection=DriverManager.getConnection(url, user, pass);

               Statement statement=connection.createStatement();
               String sql="SELECT *FROM t_user WHERE username='"+username+"' and password='"+password+"'";
               System.out.println(sql);
               ResultSet rs=statement.executeQuery(sql);           
              return rs.next();
      }

      @Test
      public void fun1() throws ClassNotFoundException, SQLException {
                boolean flag=login("zhangsan", "123");
                System.out.println(flag);
      }

控制台打印结果

true

对于表t_user内的数据
JavaWeb学习十五(PreparedStatement)_第1张图片
对于t_user表中的数据,把上面的login方法内的两个参数改成表内数据打印的都是true,反之,不是表中数据就是false
我们再看看下面吧

public boolean login(String username,String password) throws ClassNotFoundException, SQLException {
              Class.forName("com.mysql.jdbc.Driver");

               String user="root";
               String pass="T471912619";
               String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";
               Connection connection=DriverManager.getConnection(url, user, pass);

               Statement statement=connection.createStatement();
               String sql="SELECT *FROM t_user WHERE username='"+username+"' and password='"+password+"'";
               System.out.println(sql);
               ResultSet rs=statement.executeQuery(sql);           
              return rs.next();
      }

      @Test
      public void fun1() throws ClassNotFoundException, SQLException {
                    String username="a' or 'a'='a";
                    String password="a' or 'a'='a";
                boolean flag=login(username,password);
                System.out.println(flag);
      }

最终控制台打印的是true,为什么呢?我们看看这个sql语句吧

SELECT *FROM t_user WHERE username='a' or 'a'='a' and password='a' or 'a'='a'
                           false            true        false          true
                                中间or所以为true                中间or所以为true  
                                          两个true所以为true

在看看数据库查询出来的效果,因为这条sql语句对每行数据都是true,所以查询出了所有的数据

JavaWeb学习十五(PreparedStatement)_第2张图片

这就是sql攻击,那怎么避免呢?这就需要用到今天所学的PreparedStatement了

3.创建PreparedStatement对象

我们先看看API吧

JavaWeb学习十五(PreparedStatement)_第3张图片

可以看到在获取Connection对象之前我们的步骤没有发生变化,所以我们来想想代码吧!

public boolean login(String username,String password) throws ClassNotFoundException, SQLException {
          Class.forName("com.mysql.jdbc.Driver");

           String user="root";
           String pass="T471912619";
           String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";
           Connection connection=DriverManager.getConnection(url, user, pass);

           //sql模板
           String sql="SELECT *FROM t_user WHERE username=? AND password=?";
           //创建PreparedStatement对象
           PreparedStatement pstmt=connection.prepareStatement(sql);
  }

4.PreparedStatement用法

  • 给出SQL模板
  • 调用Connection的PreparedStatement的preparedStatement(String sql模板)
  • 调用pstmt的setXxx()系列方法sql模板中的?赋值
  • 调用pstmt的executeUpdate()或executeQuery(),但它的方法都没有参数
@Test
      public void fun1() throws ClassNotFoundException, SQLException {
                    String username="a' or 'a'='a";
                    String password="a' or 'a'='a";
                boolean flag=login(username,password);
                System.out.println(flag);
      }

      public boolean login(String username,String password) throws ClassNotFoundException, SQLException {
          Class.forName("com.mysql.jdbc.Driver");

           String user="root";
           String pass="T471912619";
           String url="jdbc:mysql://localhost:3306/test1?serverTimezone=UTC";
           Connection connection=DriverManager.getConnection(url, user, pass);

           //sql模板
           String sql="SELECT *FROM t_user WHERE username=? AND password=?";
           //创建PreparedStatement对象
           PreparedStatement pstmt=connection.prepareStatement(sql);

           //给参数赋值
           pstmt.setString(1,username);//给第一个问号赋值
           pstmt.setString(2,password);//给第二个问号赋值

           ResultSet rs=pstmt.executeQuery();

           return rs.next();
  }

控制台打印

false
 public void fun1() throws ClassNotFoundException, SQLException {
                    String username="zhangsan";
                    String password="123";
                boolean flag=login(username,password);
                System.out.println(flag);
      }

控制台打印

true

你可能感兴趣的:(JAVA,WEB)