JDBC基础超详细(二)(PreparedStatement与Statement的区别,避免mysql注入)

JDBC基础超详细三部曲一(连接数据库,实现增删改查四项主要功能)

在上一篇中我们完成了数据库增删改查等四项主要功能,大家发现在获取数据库操作对象时候,使用的是Statement,而在实际使用中,大部分使用的是PreparedStatement功能,那么这两个有什么区别???给大家一串代码,请大家在自己电脑中配置运行!!!

这是user表中的数据

 Statement


import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
 * @author 张硕硕
 */
public class test {
    public static void main(String [] args){
        Map<String,String> haha= test.initUi();
        System.out.println(test.login(haha)?"登陆成功":"登陆失败");
    }
    private  static Map<String ,String > initUi(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入您的用户名");
        String userName=scanner.nextLine();
        System.out.println("请输入您的登录密码");
        String password=scanner.nextLine();
        Map<String,String> userInformation=new HashMap<>();
        userInformation.put("username",userName);
        userInformation.put("password",password);
        return userInformation;
    }
    private  static boolean login(Map<String,String> userInformation){
        boolean loginY=false;
        Connection connection=null;
        Statement statement=null;
        ResultSet resultset=null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","200101");
            statement=connection.createStatement();
            String sql="select * from user where user_name= '"+userInformation.get("username")+"'and user_password= '"+userInformation.get("password")+"'";
            resultset=statement.executeQuery(sql);
            if (resultset.next()){loginY=true;}
        }
        catch (Exception e){e.printStackTrace();}

        finally {
            if (resultset!=null){try{resultset.close();}catch (Exception e){e.printStackTrace();}}
            if (statement!=null){try{statement.close();}catch (Exception e){e.printStackTrace();}}
            if (connection!=null){try{connection.close();}catch(Exception e){e.printStackTrace();}}

        }
        return loginY;
    }

}

  • 大家按照如图中信息去输入,可以惊奇的发现,账号密码完全不对,可是怎么就可以登录???

是因为在编译过程中,数据将密码传输给mysql语句,导致mysql语句句意发生改变,大家仔细查看在调试过程中,sql语句句意发生了改变,导致这个验证根本无效,可以直接通过这个登录。

PreparedStatement


import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Login {
    public static void main(String [] args){
            Map<String,String> haha= Login.initUi();
            System.out.println(Login.login(haha)?"登陆成功":"登陆失败");
    }
    private  static Map<String ,String > initUi(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入您的用户名");
        String userName=scanner.nextLine();
        System.out.println("请输入您的登录密码");
        String password=scanner.nextLine();
        Map<String,String> userInformation=new HashMap<>();
        userInformation.put("username",userName);
        userInformation.put("password",password);
        return userInformation;
    }
    private  static boolean login(Map<String,String> userInformation){
        boolean loginY=false;
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultset=null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/user","root","200101");
            String sql="select * from user where user_name= ? and user_password= ?";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1,userInformation.get("username"));
            preparedStatement.setString(2,userInformation.get("password"));
            resultset=preparedStatement.executeQuery();
            if (resultset.next()){loginY=true;}
            }
        catch (Exception e){e.printStackTrace();}

        finally {
            if (resultset!=null){try{resultset.close();}catch (Exception e){e.printStackTrace();}}
            if (preparedStatement!=null){try{preparedStatement.close();}catch (Exception e){e.printStackTrace();}}
            if (connection!=null){try{connection.close();}catch(Exception e){e.printStackTrace();}}

        }
        return loginY;
    }

}

  •  在这里大家可以看到,利用PreparedStatement就可以杜绝此类情况的发生,是因为在这个过程中,传给mysql的语句句意始终没有发生变化。

 说明

  1. 在大部分情况下,PreparedStatementStatement更加广泛,而且更加安全。
  2. PreparedStatementStatement运行更加快速,在mysql中,如果连续两条语句一模一样,这样编译器不会对语句进行重新编译,而是直接将赋值进行操作。
  3. 在部分特殊情况下,还是需要使用Statement,因为部分企业需求需要进行注入。(比如我们常见的商品按照价格排序界面,需要有order by desc/asc时,利用 PreparedStatement传输desc值或者asc值时,会为这两个值带上引号,语句无法识别,此时使用Statement更加方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值