PreparedStatement 模拟并解决sql注入

作用:

预编译sql语句执行:预防sql注入问题

sql注入:通过操作输入事先定义好的sql语句,用以达到执行代码达到对服务器进行攻击的方法

我输入的信息为账号是随便输入的:fdadf,

密码为 :' or'1'='1

也登录成功了

模拟一下sql注入



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class Test5 {
	public static void main(String[] args)  throws Exception{
		//我现在数据表中只有一个 数据   t_username='zhangsan' t_password='123';
		String url="jdbc:mysql:///TestUser";
		String userName="root";
		String PassWord="666";
		Connection con=DriverManager.getConnection(url, userName, PassWord);//创建连接	
		Scanner sc=new Scanner(System.in);
		System.out.println("请您输入账号:");
		String username2=sc.nextLine();
		System.out.println("请您输入密码:"); //模拟sql注入  输入   ' or'1'='1
		String passwold2=sc.nextLine();
		String sql="select * from tb_user where t_username='"+username2+"'and t_password=+ '"+passwold2+"' ";
		Statement st=con.createStatement();
		ResultSet rs=st.executeQuery(sql);
		System.out.println(sql); //把他输出看看sql是啥
		if(rs.next()) {//如果有数据肯定就是查到了
			System.out.println("登录成功");
		}else {
			System.out.println("登录失败");
		}
	}

}

用Navicat打卡一下,主要是拼接出现了问题 

select * from tb_user where t_username='fdadf'and t_password=+ ''or '1'='1' 

解决sql注入

1获取PrepareStatement对象

Sql语句中的参数,使用?占位符代替

String sql="select * from user where username=? and password=?";

通过Connection 对象获取,并传入对象的sql语句

PreparedStatement ps=con.prepareStatement(sql);

2设置参数值

PrepareStatement对象:setXXX(参数1,参数2):给?赋值

Xxx:数据类型  ;如setInt(参数1,参数2)

参数:

参数1:? 的位置编号 ,从1开始

参数2: ?的值(变量)

3执行sql

executeUpdate()或者 executeQuery;不需要再传sql

没有问题的登录

package lib;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class Test7 {
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub//我现在数据表中只有一个 数据   t_username='zhangsan' t_password='123';
		String url="jdbc:mysql:///TestUser";
		String userName="root";
		String PassWord="666";
		Connection con=DriverManager.getConnection(url, userName, PassWord);//创建连接	
		Scanner sc=new Scanner(System.in);
		System.out.println("请您输入账号:");
		String username2=sc.nextLine();
		System.out.println("请您输入密码:"); 
		String passwold2=sc.nextLine();
		String sql="select * from tb_user where t_username=?and t_password=?";
		PreparedStatement ps=con.prepareStatement(sql);//创建PrepareStatement对象
		//设置参数
		ps.setString(1, username2);  //设置第一个问号
		ps.setString(2, passwold2); //设置第二个个问号
		ResultSet rs=ps.executeQuery(); //执行sql
		if(rs.next()) {//如果有数据肯定就是查到了
			System.out.println("登录成功");
		}else {
			System.out.println("登录失败");
		}
	}
}


	




PrepareStatement原理

好处:

预编译Sql,性能更高

防止sql注入,将敏感字符进行转义

1:PrepareStatement预编译功能开启:useServerPrepStmts=true ,在url中添加

String url="jdbc:mysql:///TestUser?useServerPrepStmts=true";

2配置Mysql执行日志(重启mysql服务器后生效) 配置到ini文件中

log-output=FILE

general-log=1

general_log_file="D:/mysql.log"   

show-query-log=1

slow_query_log_file="D:\mysql_slow.log"

long_query_time=2

PrepareStatement原理:

1在获取PrepareStatement对象时,将sql语句发送给mysql服务器,进行检查,编译(这些步骤很耗时)

2执行时就不用再进行这些步骤了,速度更快

3如果sql模板一样,则只需进行一次检查,,编译

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小萌新上大分

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

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

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

打赏作者

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

抵扣说明:

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

余额充值