package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
/*
* Java程序实现用户登录,用户名和密码,数据库检查
* 演示如何防止注入攻击
*
* Statement是一个接口实现类,作用执行SQL语句,返回结果集
* Statement有一个子接口PreparedStatement,用来SQL预编译存储,多次高效的执行SQL,还可以防止被攻击
* PreparedStatement的实现类也在数据库的驱动中.
*
* 如何获取接口的实现类?
*
* PreparedStatement prepareStatement(String sql):
* 是Connection数据库连接对象的方法,可以获取PreparedStatement接口的实现类
*
*/
public class JDBCDemo4 {
public static void main(String[] args) throws ClassNotFoundException,
SQLException {
// url,username,password是自己设定的
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
Connection con = DriverManager.getConnection(url, "root", "root");
// sql语句,使用此子接口,sql语句中所有参数全部采用问号占位符
Scanner sc = new Scanner(System.in);
String username = sc.nextLine();
String password = sc.nextLine();
String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=? ";
// 调用Connection接口的方法PreparedStatement
PreparedStatement pst = con.prepareStatement(sql);
// 调用pst对象的set方法,设置问号占位符上的参数
// 第一个参数为第几个问号,第二个为参数的名字
pst.setObject(1, username);
pst.setObject(2, password);
// 调用方法,执行sql语句,获取结果集
ResultSet rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("username") + " "
+ rs.getString("password"));
}
//释放资源
rs.close();
pst.close();
con.close();
}
}
结果:
注入攻击:
会发现没有反应,
使用Statement子接口PreparedStatement,成功防止了注入攻击.