jdbc之防sql注入攻击
1、SQL注入攻擊:
??? 由于dao中執行的SQL語句是拼接出來的,其中有一部分內容是由用戶從客戶端傳入,所以當用戶傳入的數據中包含sql關鍵字時,就有可能通過這些關鍵字改變sql語句的語義,從而執行一些特殊的操作,這樣的攻擊方式就叫做sql注入攻擊
??
? ?PreparedStatement利用預編譯的機制將sql語句的主干和參數分別傳輸給數據庫服務器,從而使數據庫分辨的出哪些是sql語句的主干哪些是參數,這樣一來即使參數中帶了sql的關鍵字,數據庫服務器也僅僅將他當作參數值使用,關鍵字不會起作用,從而從原理上防止了sql注入的問題
??PreparedStatement主要有如下的三個優點:
?? 1.可以防止sql注入
???2.由于使用了預編譯機制,執行的效率要高于Statement
???3.sql語句使用?形式替代參數,然后再用方法設置?的值,比起拼接字符串,代碼更加優雅.
? PreparedStatement 與Statment比較
?????????????????? 1)語法不同:PreparedStatement可以使用預編譯的sql,而Statment只能使用靜態的sql
?????????????????? 2)效率不同: PreparedStatement可以使用sql緩存區,效率比Statment高
?????????????????? 3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。
?
/*** PreparedStatement執行sql語句* **/ public class Demo1 {/*** 增加*/@Testpublic void testInsert() {Connection conn = null;PreparedStatement stmt = null;try {//1.獲取連接conn = JdbcUtil.getConnection();//2.準備預編譯的sqlString sql = "INSERT INTO student(NAME,gender) VALUES(?,?)"; //?表示一個參數的占位符//3.執行預編譯sql語句(檢查語法)stmt = conn.prepareStatement(sql);//4.設置參數值/*** 參數一: 參數位置 從1開始*/stmt.setString(1, "李四");stmt.setString(2, "男");//5.發送參數,執行sqlint count = stmt.executeUpdate();System.out.println("影響了"+count+"行");} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {JdbcUtil.close(conn, stmt);}}/*** 修改*/@Testpublic void testUpdate() {Connection conn = null;PreparedStatement stmt = null;try {//1.獲取連接conn = JdbcUtil.getConnection();//2.準備預編譯的sqlString sql = "UPDATE student SET NAME=? WHERE id=?"; //?表示一個參數的占位符//3.執行預編譯sql語句(檢查語法)stmt = conn.prepareStatement(sql);//4.設置參數值/*** 參數一: 參數位置 從1開始*/stmt.setString(1, "王五");stmt.setInt(2, 9);//5.發送參數,執行sqlint count = stmt.executeUpdate();System.out.println("影響了"+count+"行");} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {JdbcUtil.close(conn, stmt);}}/*** 刪除*/@Testpublic void testDelete() {Connection conn = null;PreparedStatement stmt = null;try {//1.獲取連接conn = JdbcUtil.getConnection();//2.準備預編譯的sqlString sql = "DELETE FROM student WHERE id=?"; //?表示一個參數的占位符//3.執行預編譯sql語句(檢查語法)stmt = conn.prepareStatement(sql);//4.設置參數值/*** 參數一: 參數位置 從1開始*/stmt.setInt(1, 9);//5.發送參數,執行sqlint count = stmt.executeUpdate();System.out.println("影響了"+count+"行");} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {JdbcUtil.close(conn, stmt);}}/*** 查詢*/@Testpublic void testQuery() {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {//1.獲取連接conn = JdbcUtil.getConnection();//2.準備預編譯的sqlString sql = "SELECT * FROM student"; //3.預編譯stmt = conn.prepareStatement(sql);//4.執行sqlrs = stmt.executeQuery();//5.遍歷rswhile(rs.next()){int id = rs.getInt("id");String name = rs.getString("name");String gender = rs.getString("gender");System.out.println(id+","+name+","+gender);}} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {//關閉資源 JdbcUtil.close(conn,stmt,rs);}} }eg:模擬登陸
/*** 模擬用戶登錄效果* **/ public class Demo2 {//模擬用戶輸入//private String name = "ericdfdfdfddfd' OR 1=1 -- ";private String name = "eric";//private String password = "123456dfdfddfdf";private String password = "123456";/*** Statment存在sql被注入的風險*/@Testpublic void testByStatement(){Connection conn = null;Statement stmt = null;ResultSet rs = null;try {//獲取連接conn = JdbcUtil.getConnection();//創建Statmentstmt = conn.createStatement();//準備sqlString sql = "SELECT * FROM users WHERE NAME='"+name+"' AND PASSWORD='"+password+"'";//執行sqlrs = stmt.executeQuery(sql);if(rs.next()){//登錄成功System.out.println("登錄成功");}else{System.out.println("登錄失敗");}} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {JdbcUtil.close(conn, stmt ,rs);}}/*** PreparedStatement可以有效地防止sql被注入*/@Testpublic void testByPreparedStatement(){Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {//獲取連接conn = JdbcUtil.getConnection();String sql = "SELECT * FROM users WHERE NAME=? AND PASSWORD=?";//預編譯stmt = conn.prepareStatement(sql);//設置參數stmt.setString(1, name);stmt.setString(2, password);//執行sqlrs = stmt.executeQuery();if(rs.next()){//登錄成功System.out.println("登錄成功");}else{System.out.println("登錄失敗");}} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {JdbcUtil.close(conn, stmt ,rs);}} }?
轉載于:https://www.cnblogs.com/flei/p/6727520.html
總結
以上是生活随笔為你收集整理的jdbc之防sql注入攻击的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这里先发布一个,自己写得unityUI的
- 下一篇: 30种优化查询速度的方法