预编译sql语句执行:预防sql注入问题
sql注入:通过操作输入事先定义好的sql语句,用以达到执行代码达到对服务器进行攻击的方法
我输入的信息为账号是随便输入的:fdadf,
密码为 :' or'1'='1
也登录成功了
-
-
- 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'
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("登录失败");
- }
- }
- }
-
-
-
-
-
-
-
好处:
预编译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
1在获取PrepareStatement对象时,将sql语句发送给mysql服务器,进行检查,编译(这些步骤很耗时)
2执行时就不用再进行这些步骤了,速度更快
3如果sql模板一样,则只需进行一次检查,,编译