Java-JDBC-PreparedStatement和SQL注入
目錄
內容
1、登錄案例
-
需求:輸入用戶名和密碼,如果用戶名和密碼同數據庫中存儲的用戶名和密碼相同,則運行登錄,否則不允許登錄
-
步驟:
-
創建login表
-
username字段
-
password字段
create table login( id int primary key auto_increment, username varchar(20) not null, password varchar(100) not null );
-
-
插入測試數據
insert into login(username, password) values ('zhangsan', 'a123'), ('lishi', '3f2f3');
-
圖示1-1:
-
編寫登錄邏輯
package cn.gaogzhen.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Scanner; import cn.gaogzhen.domain.Emp; import cn.gaogzhen.util.JDBCUtils; public class JDBCDemo7 { public static void main(String[] args) throws SQLException { Scanner sc = new Scanner(System.in); System.out.println("請輸入用戶名:"); String username = sc.nextLine().trim(); System.out.println("請輸入密碼:"); String password = sc.nextLine().trim(); String res = login(username, password)? "登錄成功": "登錄失敗"; System.out.println(res); } public static boolean login(String username, String password) throws SQLException { if(username == null || password == null) return false; Connection conn = JDBCUtils.getConnection(); String sql = "select * from login where username = '" + username +"' and password = '" + password + "'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); boolean flag = rs.next(); JDBCUtils.close(rs, stmt, conn); return flag; } }
-
測試結果:
// 成功 請輸入用戶名: zhangsan 請輸入密碼: a123 登錄成功 // 失敗 請輸入用戶名: fewf 請輸入密碼: fwfe 登錄失敗
-
-
注意:JDBCUtils類爲上一篇JDBCUtils工具類博文中編寫的工具類
2、SQL注入
在#1登錄案例中,如何密碼輸入
as' or '1' = '1#
用戶名隨意,試一下會發生什麼?
測試結果:
請輸入用戶名:
fasdfa
請輸入密碼:
sfas' or '1'='1
登錄成功
這就是SQL注入問題,關於SQL注入的詳情,有興趣的小夥伴可自行查閱相關文檔。那麼這裏怎麼解決SQL注入問題呢?這就是需要用到下面要介紹的PreparedStatement對象。
3、PreparedStatement
- 表示預編譯的SQL語句的對象:用?代替參數
- 步驟
- 導入jar包:mysql-connector-java-版本號-bin.jar
- 註冊驅動
- 獲取連接對象Connection
- sql語句
- 注意:sql語句的參數使用?作爲佔位符,如select * from login where username = ? and password = ?
- 獲取執行sql語句的對象PreparedStatement
- 給?賦值
- 方法:setXXX(參數1, 參數2)
- 參數1:?的位置編號,從1開始
- 參數2:?的值
- 方法:setXXX(參數1, 參數2)
- 執行sql操作
- 得到結果
- 解析結果
- 釋放資源
那麼我們現在使用PreparedStament類對象防止上面的SQL注入
-
實現代碼3-1:
package cn.gaogzhen.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; import cn.gaogzhen.util.JDBCUtils; public class JDBCDemo8 { public static void main(String[] args) throws SQLException { Scanner sc = new Scanner(System.in); System.out.println("請輸入用戶名:"); String username = sc.nextLine().trim(); System.out.println("請輸入密碼:"); String password = sc.nextLine().trim(); sc.close(); String res = login(username, password)? "登錄成功": "登錄失敗"; System.out.println(res); } public static boolean login(String username, String password) throws SQLException { if(username == null || password == null) return false; Connection conn = JDBCUtils.getConnection(); String sql = "select * from login where username = ? and password = ?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, username); pstm.setString(2, password); ResultSet rs = pstm.executeQuery(); boolean flag = rs.next(); JDBCUtils.close(rs, pstm, conn); return flag; } }
測試結果:
請輸入用戶名:
sdfasf
請輸入密碼:
sdfas' or '1'='1#
登錄失敗
後記 :
本項目爲參考某馬視頻開發,相關視頻及配套資料可自行度娘或者聯繫本人。上面爲自己編寫的開發文檔,持續更新。歡迎交流,本人QQ:806797785
前端項目源代碼地址:https://gitee.com/gaogzhen/vue-leyou
後端JAVA源代碼地址:https://gitee.com/gaogzhen/JAVA