当前位置: 代码迷 >> 综合 >> JDBC 06 PreparedStatement(安全的执行SQL)
  详细解决方案

JDBC 06 PreparedStatement(安全的执行SQL)

热度:103   发布时间:2023-11-24 13:09:26.0

2.2 prepareStatement(安全的执行SQL)


有备而来的 执行对象!(安全还不说,执行的效率居然还比 Statement 对象 要高!)

为什么可以防止 SQL 注入:因为它会把 关键的地方 让你使用 参数的形式 来进行设置完整的SQL语句。而 一旦用这种形式,我们就可以把 你需要设置进来的这个 关键的字符串 用 '' 给包进去!如果 你设置的字符串 里面带有 一些特殊字符,比如 ' 单引号就会被直接 干掉(删除掉)!

为什么效率高呢:因为 以 参数形式进入 收录 你输入的关键字符串时,就需要 提前 预编译 SQL语句,也就是你得 先给 preparedStatement 一个 SQL 语句的模板,在 这条 预编译的 SQL 语句中,?(问号) 就代表着 你要进行设置 的 参数字符串。

步骤如下:

  1. 创建 preparedStatement 对象
String ysql = "select * from `users` where `NAME`=? and `PASSWORD`=?";
st = conn.prepareStatement(ysql);//预编译 sql 语句,但不执行

该 对象如果 创建的话,需要 提供一个 预编译的 SQL 语句模板。(? 就代表着 你需要 设置的关键字符串!我们也将其称为 SQL 语句模板的 参数。

  1. 设置参数的值
st.setString(1,username);
st.setString(2,password);

SQL 语句模板 的 参数 下标 是从 1 开始的,与传统的 0 开始 不一样。

  1. 执行 SQL 语句
rs = st.executeQuery();while(rs.next()){
    System.out.println(rs.getInt("id") + "|" + rs.getString("NAME")+"|"+ rs.getObject("PASSWORD") + "|"+rs.getString("email")+"|" + rs.getDate("birthday"));}
  1. 测试正常登录
login("罗翔", "159159");

在这里插入图片描述
5. 测试 SQL 注入

package com.muquanyu.lesson02;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class prepareStatementDemo {
    public static void main(String[] args) {
    login("罗翔' or 1='1", "159159' or 1='1");}public static void login(String username,String password){
    Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try {
    conn = JdbcUtils.getConnection();String ysql = "select * from `users` where `NAME`=? and `PASSWORD`=?";st = conn.prepareStatement(ysql);//预编译 sql 语句,但不执行//设置 参数的值st.setString(1,username);st.setString(2,password);//执行 预编译的SQL 语句(此时 SQL 语句 的参数已被设置,变为了 完整的 SQL)rs = st.executeQuery();while(rs.next()){
    System.out.println(rs.getInt("id") + "|" + rs.getString("NAME")+"|"+ rs.getObject("PASSWORD") + "|"+rs.getString("email")+"|" + rs.getDate("birthday"));}} catch (SQLException e) {
    e.printStackTrace();}}
}

在这里插入图片描述
这就是 因为 ’ 已经被干掉了。

实际上 你提供的username 和 password 是下面的那样:

username :‘罗翔 or 1=1’ (哪有这个 username 呀。。)
password :'159159 or 1=1’

但是我们话又说过来,真的 防止了吗?好像 这个 防止 只能防住 一些 表层的操作。比如说 无法直接 通过 这种输入用户名和密码 来注入 SQL了。但是 你无法保证 以其它更牛的方式来进行注入 SQL。

  相关解决方案