JDBC-05:PrepardeStatement解决SQL注入问题

PrepardeStatement解决SQL注入问题
备注

(该篇文章也属于下列文章的一个进一步引申)

User类代码
package com.jsm1.java1;

public class User {

   private String user;
   private String password;

   public User() {
   }

   public User(String user, String password) {
      super();
      this.user = user;
      this.password = password;
   }

   @Override
   public String toString() {
      return "User [user=" + user + ", password=" + password + "]";
   }

   public String getUser() {
      return user;
   }

   public void setUser(String user) {
      this.user = user;
   }

   public String getPassword() {
      return password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

}
测试代码
package com.jsm4;

import com.jsm1.java1.User;
import com.util.JDBCUtils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Scanner;

public class sqlTest {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String user = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine();
//    并且存在SQL注入的问题:
      /*
      SELECT user,password FROM user_table WHERE user='1' or ' AND password= '=1 or '1' = '1'

       */

        //需要拼写sql语句
        String sql="SELECT user,password FROM user_table WHERE user=  ?  AND password = ? ";

        User user1 = test3(User.class,sql,user,password);
        if (user1!=null){
            System.out.println("登录成功!!");
        }else {
            System.out.println("登录失败!");
        }
    }
    
    public static  <T>T test3(Class<T> clazz,String sql, Object...args) throws Exception {
        Connection conn = JDBCUtils.getCollections();
        PreparedStatement ps = conn.prepareStatement(sql);
        for (int i = 0; i <args.length ; i++) {
            ps.setObject(i+1,args[i]);//填充占位符
        }
        ResultSet rs = ps.executeQuery();
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        if (rs.next()){
            T t = clazz.newInstance();
            for (int i = 0; i <columnCount ; i++) {
                Object value = rs.getObject(i + 1);
                String columnLabel = rsmd.getColumnLabel(i+1);
                Field field = clazz.getDeclaredField(columnLabel);
                field.setAccessible(true);
                field.set(t,value);
            }
            return t;
        }
        JDBCUtils.closeResource(conn,ps,rs);
        return null;
    }
}
运行结果

在这里插入图片描述

解决sql问题的原理

先见PrepardeStatement的API

在这里插入图片描述

这里说到了,预编译sql语句,这里的sql语句:

SELECT user,password FROM user_table WHERE user=  ?  AND password = ? 

原理:在填充占位符之前,PrepardeStatement就已经说明了谁AND谁的关系,也就是且的关系,在填占位符之前和之后,这种关系是不会改变的,statement不靠谱是因为它虽然也想表达谁且谁的关系,但是它没有预编译的过程,所以它直接拿一整个sql语句去执行,在sql注入之后,就改变了原本的关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士曼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值