一、使用 statement 存在的安全問題
(1)SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字符串的拼接。會造成安全性問題
* 輸入用戶隨便,輸入密碼:a' or 'a' = 'a
* select * from user where username = 'admin' and password = 'a' or 'a' = 'a';
之所以這樣輸入:a' or 'a' = 'a
是爲了按照對應輸入的sql語句,達到閉合的效果:
String sql = "select * from user where username = '" + username + "' " +
"and password = '"+ password + "'";
可以發現這裏通過構造特殊的恆等式,能跳過密碼驗證實現登錄。
二、使用 PreparedStatement 執行sql的對象
- 解決sql注入問題:使用
PreparedStatement
對象來解決 - 預編譯的SQL:參數使用?作爲佔位符
- 步驟:
(1)導入驅動jar包 mysql-connector-java-5.1.37-bin.jar
(2)註冊驅動
(3)獲取數據庫連接對象 Connection
(4)定義sql
* 注意:sql的參數使用?作爲佔位符。 如:select * from user where username = ? and password = ?;
(5)獲取執行sql語句的對象 PreparedStatement Connection.prepareStatement(String sql)
(6)給?賦值:
* 方法: setXxx(參數1,參數2)
* 參數1:?的位置編號 從1 開始
* 參數2:?的值
(7)執行sql,接受返回結果,不需要傳遞sql語句
(8)處理結果
(9)釋放資源
- 注意:後期都會使用PreparedStatement來完成增刪改查的所有操作
* 可以防止SQL注入
* 效率更高
三、代碼實例
package jdbc;
import java.sql.*;
import java.util.Scanner;
public class JdbcDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入用戶名:");
String user = scanner.nextLine();
System.out.println("請輸入密碼:");
String password = scanner.nextLine();
boolean login = new JdbcDemo().login(user, password);
if (login) {
System.out.println("登錄成功!");
}else {
System.out.println("用戶名或密碼錯誤!");
}
}
public boolean login(String username,String password){
if (username == null || password == null) {
return false;
}
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
// 執行 sql 的對象 prepareStatement
preparedStatement = connection.prepareStatement(sql);
// 設置參數
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
// 執行sql
resultSet = preparedStatement.executeQuery();
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(resultSet,preparedStatement,connection);
}
return false;
}
}