【JAVA高级】 您所在的位置:网站首页 java中throws是什么 【JAVA高级】

【JAVA高级】

#【JAVA高级】| 来源: 网络整理| 查看: 265

💖SQL注入 ✨什么是SQL注入

        在用户输入的数据中有SQL关键字或语法,并且关键字或语法参与了SQL语句的编译。导致SQL语句编译后的条件为true,一直得到正确的结果。这种现象就是SQL注入。

✨SQL注入的效果的演示 💫SQL注入代码 package cn.bdqn.demo03; ​ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; ​ public class Login { ​ public static void main(String[] args) throws ClassNotFoundException, SQLException { //创建Scanner类对象,从控制台获取用户名和密码数据 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String user = sc.nextLine();//使用nextLine()方法获取字符串 System.out.println("请输入密码:"); String pwd = sc.nextLine();//使用nextLine()方法获取字符串 //1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2、获取连接对象 String url = "jdbc:mysql://127.0.0.1:3306/java221804"; String dbuser = "root"; String pssword = "123456"; Connection connection = DriverManager.getConnection(url, dbuser, pssword); //3、获取发送SQL语句的对象 Statement statement =connection.createStatement(); //编写SQL语句 String sql = "SELECT * FROM user WHERE username='"+user+"' AND pssword = '"+pwd+"';"; //4、执行SQL语句 ResultSet resultSet=statement.executeQuery(sql); if(resultSet.next()){ System.out.println("用户名和密码正确,登录成功"); }else{ System.out.println("用户名或密码不正确,登录失败"); } //6、关闭资源 resultSet.close(); statement.close(); connection.close(); sc.close(); } } 复制代码 💫SQL注入效果

输入错误的用户名和密码,提示登录失败:

 输入错误的用户名和密码,提示登录成功:产生了SQL注入

        上面案例代码中,当你的用户名为 abc' or 1=1;# 密码为123,拼接到SQL语句中,变成如下效果:

SELECT * FROM user WHERE username='abc' or 1=1;#' AND pssword = '123'; 复制代码

        此SQL语句or 后面1=1永远正确,#后面的成了注释,所以这条语句会将表中所有的数据查询出来,然后再做数据判断的时候,就会得到正确结果,从而说用户名和密码正确,登录成功。

✨如何避免SQL注入

        使用PreparedStatement代替Statement可以有效防止SQL注入的发生。由于SQL注入产生的原因是在用户输入数据对SQL整合,整合后再发送到数据库进行编译产生的。

        所以为了避免SQL注入,就需要SQL语句在用户输入数据前就进行编译,成为完整的SQL语句,编译完成后再进行数据填充。这个操作需要使用PrepareStatement实现。

        PreparedStatement利用预编译的机制将sql语句的主干和参数分别传输给数据库服务器,从而使数据库分辨的出哪些是sql语句的主干哪些是参数,这样一来即使参数中带了sql的关键字,数据库服务器也仅仅将他当作参数值使用,关键字不会起作用,从而从原理上防止了sql注入的问题。

💖PrepareStatement解决SQL注入

        PreparedStatement接口继承了Statement接口,执行SQL语句的方法与Statement执行SQL语句的方法相同。

✨PreparedStatement的应用

PreparedStatement的作用:

预编译SQL语句,效率高 安全,避免SQL注入 可以动态的填充数据,执行多个同结构的SQL语句 💫参数标记

//预编译SQL语句,SQL中的所有参数由?符号占位,这被称为参数标记。在执行SQL语句之前,必须为每个参数提供值。

        String sql = "select * from user where userName = ? and pssword=?;";

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

💫动态参数绑定

        preparedStatement.sexXxx(下标,值):参数下标从1开始,为指定参数下标绑定值。Xxx表示数据类型。

//绑定参数,有多少个?绑定多少个参数值

        preparedStatement.setString(1, userName);

        preparedStatement.setString(2, pwd);

✨综合案例 package cn.bdqn.demo02; ​ import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; ​ public class PreparedStatementDemo01 { ​ public static void main(String[] args) throws ClassNotFoundException,SQLException { ​ Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String userName = sc.nextLine(); System.out.println("请输入密码:"); String pwd = sc.nextLine(); ​ // 1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2、获得连接 String url = "jdbc:mysql://localhost:3306/java2217"; String user = "root"; String pssword = "123456"; Connection connection = DriverManager.getConnection(url, user, pssword); // 3、获取发送SQL对象 String sql = "select * from user where userName = ? and pssword=?;"; PreparedStatement preparedStatement = connection.prepareStatement(sql); // 4、绑定参数,有多少个?绑定多少个参数值 preparedStatement.setString(1, userName); preparedStatement.setString(2, pwd); // 5、执行SQL语句,并处理结果 ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { System.out.println("用户名和密码正确,登录成功"); } else { System.out.println("用户名或密码错误,登录失败"); } // 6、释放资源:与关闭流的方式一样,先开的后关,后开的先关 resultSet.close(); preparedStatement.close(); connection.close(); sc.close(); } } 复制代码 ✨PreparedStatement总结

PreparedStatement主要有如下的三个优点:

        可以防止sql注入 由于使用了预编译机制,执行的效率要高于Statement sql语句使用?形式替代参数,然后再用方法设置?的值,比起拼接字符串,代码更加优雅.

PreparedStatement 与Statment比较:

        语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql 效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高 安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。

💖必须使用Statement的情况

        当sql语句中必须用到字符串拼接时,则必须使用Statement

public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.print("升序输入asc,降序输入desc:"); String order = s.nextLine(); // 定义变量 Connection connection = null; Statement statement = null; ResultSet rs = null; try { // 注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 获取连接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/MyTest","root", "********"); // 获取数据库操作对象 statement = connection.createStatement(); // 执行sql String sql = "select * from emp order by sal " + order; rs = statement.executeQuery(sql); // 处理查询结果集 while(rs.next()){ String ename = rs.getString("ename"); double sal = rs.getDouble("sal"); System.out.println("姓名:" + ename + ",薪资:" + sal); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { // 释放资源 if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } } 复制代码 💖投票传送门(欢迎伙伴们投票)

文章知识点与官方知识档案匹配,可进一步学习相关知识

Java技能树使用JDBC操作数据库JDBC概述97308 人正在系统学习中

不迁怒,不贰过。小知识,大智慧

微信名片



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有