Java學習筆記47(JDBC、SQL注入攻擊原理以及解決)

JDBC:java的數據庫鏈接java

JDBC本質是一套API,由開發公司定義的類和接口mysql

這裏使用mysql驅動,是一套類庫,實現了接口sql

驅動程序類庫,實現接口重寫方法,由驅動程序操做數據庫數據庫

 

JDBC操做步驟:安全

1.註冊驅動url

2.得到鏈接spa

3.得到語句執行平臺code

4.執行sql語句對象

5.處理結果blog

6.釋放資源

 

1.導入jar包,能夠在網上下載到,這裏使用的是:mysql-connector-java-5.1.37-bin.jar

註冊驅動:

package demo; import java.sql.DriverManager; import java.sql.SQLException; import com.mysql.jdbc.Driver; public class JDBCDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException { //註冊驅動 //DriverManager.registerDriver(new Driver()); //不推薦上邊這種方法,建議用反射技術,將驅動類加入內存
        Class.forName("com.mysql.jdbc.Driver"); } }

 

2.得到鏈接:

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JDBCDemo { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); //得到數據庫鏈接
        String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url,username,password); System.out.println(con); } }

 

3.獲取語句執行平臺

經過數據庫鏈接對象,獲取到sql語句的執行者對象

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class JDBCDemo { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url,username,password); //獲取語句執行平臺
        Statement stat = con.createStatement(); System.out.println(stat); } }

 

4.執行sql語句:

準備數據:

CREATE TABLE sort( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(100), sprice DOUBLE, sdesc VARCHAR(5000) ); INSERT INTO sort(sname,sprice,sdesc) VALUES('家電',2000,'促銷'), ('傢俱',8900,'價格上漲'), ('玩具',300,'賺錢'), ('生鮮',500.99,'促銷'), ('服裝',24000,'促銷'), ('洗滌',50,'促銷'); SELECT * FROM sort;

 

執行sql語句:

1.增刪改

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class JDBCDemo { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url,username,password); Statement stat = con.createStatement(); //執行sql語句 //這種方法注意:只能使用insert,delete,update語句
        int row = stat.executeUpdate("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽車',2000,'促銷');"); System.out.println(row); //釋放資源
 stat.close(); con.close(); } }

 

2.查詢

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCDemo { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url,username,password); Statement stat = con.createStatement(); //查詢sql語句
        String sql= "SELECT * FROM sort"; //這個方法用於執行sql中的select查詢
        ResultSet rs = stat.executeQuery(sql); //處理結果集
        while(rs.next()){ //獲取每列數據
            System.out.println(rs.getInt("sid")+"   "+rs.getString("sname")+
                    "   "+rs.getDouble("sprice")+"   "+rs.getString("sdesc")); } rs.close(); stat.close(); con.close(); } }

輸出:



 

SQL注入攻擊簡單案例:

CREATE TABLE users( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100), PASSWORD VARCHAR(100) ); INSERT INTO users (username,PASSWORD) VALUES ('a','1'),('b','2');
package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /* * Java程序實現用戶登陸,用戶名和密碼,數據庫檢查 * 演示被別人注入攻擊 */
public class JDBCDemo { public static void main(String[] args)throws Exception { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url, username, password); Statement stat = con.createStatement(); Scanner sc = new Scanner(System.in); String user = sc.nextLine(); String pass = sc.nextLine(); //執行SQL語句,數據表,查詢用戶名和密碼,若是存在,登陸成功,不存在登陸失敗
        String sql = "SELECT * FROM users WHERE username='"+user+"' AND PASSWORD='"+pass+"'"; System.out.println(sql); ResultSet rs = stat.executeQuery(sql); while(rs.next()){ System.out.println(rs.getString("username")+"   "+rs.getString("password")); } rs.close(); stat.close(); con.close(); } }

正常狀況,必須輸入a,1或者b,2才能夠登陸成功

這裏若是這樣輸入:

1=1恆成立,or兩邊只要有一邊成立就會成功,這裏就實現了最簡單的sql注入攻擊

 

 

解決:


使用PrepareStatement接口

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /* * Java程序實現用戶登陸,用戶名和密碼,數據庫檢查 * 防止注入攻擊 * Statement接口實現類,做用執行SQL語句,返回結果集 * 有一個子接口PreparedStatement (SQL預編譯存儲,屢次高效的執行SQL) * PreparedStatement的實現類數據庫的驅動中,如何獲取接口的實現類 * * 是Connection數據庫鏈接對象的方法 * PreparedStatement prepareStatement(String sql) */
public class JDBCDemo { public static void main(String[] args)throws Exception { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "xuyiqing"; Connection con = DriverManager.getConnection(url, username, password); Scanner sc = new Scanner(System.in); String user = sc.nextLine(); String pass = sc.nextLine(); //執行SQL語句,數據表,查詢用戶名和密碼,若是存在,登陸成功,不存在登陸失敗
        String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=?"; //調用Connection接口的方法prepareStatement,獲取PrepareStatement接口的實現類 //方法中參數,SQL語句中的參數所有采用問號佔位符
        PreparedStatement pst = con.prepareStatement(sql); System.out.println(pst); //調用pst對象set方法,設置問號佔位符上的參數
        pst.setObject(1, user); pst.setObject(2, pass); //調用方法,執行SQL,獲取結果集
        ResultSet rs = pst.executeQuery(); while(rs.next()){ System.out.println(rs.getString("username")+"   "+rs.getString("password")); } rs.close(); pst.close(); con.close(); } }

 

發現這個接口更安全,因此建議使用這個接口實現增刪改查

使用PrepareStatement接口,實現數據表的更新操做

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; /* * 使用PrepareStatement接口,實現數據表的更新操做 */
public class JDBCDemo { public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username="root"; String password="xuyiqing"; Connection con = DriverManager.getConnection(url, username, password); //拼寫修改的SQL語句,參數採用?佔位
        String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?"; //調用數據庫鏈接對象con的方法prepareStatement獲取SQL語句的預編譯對象
        PreparedStatement pst = con.prepareStatement(sql); //調用pst的方法setXXX設置?佔位
        pst.setObject(1, "車"); pst.setObject(2, 49988); pst.setObject(3, 7); //調用pst方法執行SQL語句
 pst.executeUpdate(); pst.close(); con.close(); } }

 

 PrepareStatement接口實現數據表的查詢操做

package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; /* * PrepareStatement接口實現數據表的查詢操做 */
public class JDBCDemo { public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/mybase"; String username="root"; String password="xuyiqing"; Connection con = DriverManager.getConnection(url, username, password); String sql = "SELECT * FROM sort"; PreparedStatement pst = con.prepareStatement(sql); //調用pst對象的方法,執行查詢語句,Select
        ResultSet rs=pst.executeQuery(); while(rs.next()){ System.out.println(rs.getString("sid")+"  "+rs.getString("sname")+"  "+rs.getString("sprice")+"  "+rs.getString("sdesc")); } rs.close(); pst.close(); con.close(); } }
相關文章
相關標籤/搜索