PreparedStatement 可以防止SQL注入,并且效率更高。
测试插入
示例:
package jdbc.lesson;
import jdbc.lesson.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();// 获取数据库连接
statement = connection.createStatement(); // 获得SQL执行对象
String sql = "INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)\n" +
"VALUES(4,'周天天','123456','[email protected]','2000-12-04');";
int i = statement.executeUpdate(sql);
if (i > 0) {
System.out.println("插入数据成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}
}
}
结果:
测试查询
示例:
package jdbc.lesson.utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestQuery {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();
String sql = "SELECT * FROM `users` WHERE `id` = ?;";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);
// 执行
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println("id = " + resultSet.getObject("id"));
System.out.println("NAME = " + resultSet.getObject("NAME"));
System.out.println("PASSWORD = " + resultSet.getObject("PASSWORD"));
System.out.println("email = " + resultSet.getObject("email"));
System.out.println("birthday = " + resultSet.getObject("birthday"));
System.out.println("");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, preparedStatement, resultSet);
}
}
}
结果:
防止SQL注入
1. 正常登录
package jdbc.lesson;
import jdbc.lesson.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// SQL注入问题
public class SQLInjection02 {
public static void main(String[] args) {
login("周天天", "123456");// 正常登录
//login("'or ' 1=1", "'or' 1=1");// 异常登录
}
// 登录业务
public static void login(String username, String password) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();// 获取数据库连接
String sql = "SELECT * FROM `users` WHERE `NAME`= ? AND `PASSWORD`= ?;";
statement = connection.prepareStatement(sql); // 获得SQL执行对象
statement.setObject(1, username);
statement.setObject(2, password);
resultSet = statement.executeQuery();
while (resultSet.next()) {
System.out.println("name = " + resultSet.getObject("name"));
System.out.println("password = " + resultSet.getObject("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}
}
}
结果:
2. 异常登录(这里并不会返回所有结果)
如需对比请看 SQL注入问题
package jdbc.lesson;
import jdbc.lesson.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// SQL注入问题
public class SQLInjection02 {
public static void main(String[] args) {
// login("周天天", "123456");// 正常登录
login("'or ' 1=1", "'or' 1=1");// 异常登录
}
// 登录业务
public static void login(String username, String password) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();// 获取数据库连接
String sql = "SELECT * FROM `users` WHERE `NAME`= ? AND `PASSWORD`= ?;";
statement = connection.prepareStatement(sql); // 获得SQL执行对象
statement.setObject(1, username);
statement.setObject(2, password);
resultSet = statement.executeQuery();
while (resultSet.next()) {
System.out.println("name = " + resultSet.getObject("name"));
System.out.println("password = " + resultSet.getObject("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}
}
}
结果:
总结
PreparedStatement防止Sql注入的本质是把传递进来的参数当作字符
假设其中存在转义字符,直接忽略,’ 会被直接转移