JDBC課程4--使用PreparedStatement進行增刪查改, JDBCTools新增對應的的功能,模擬SQL注入
阿新 • • 發佈:2018-11-20
主要內容:
熟悉了使用PreparedStatement的優勢,沒有使用封裝和使用封裝的方法進行實現了;
以及JDBCTools新增update_sql(String sql,Object...args) 和query_sql(String sql,Object...args)兩個功能模組,分別實現了SQL的update和select的功能.
瞭解了sql注入,以及實現了模擬注入和PreparedStatement阻止注入的樣例.
PreparedStatement的使用步驟:
1.建立PreparedStatement,建立同時傳入一個sql
* String sql="insert into examstudent values(?,?,?)";
* //2.呼叫PreparedStatement 的setXXX(int index,Object val)設定佔位符的值,
* Index從1開始,
* //3.使用方法執行SQL語句: 執行 查詢 或者 升級 : executeQuery() 或executeUpdate()
* //因此,省略了SQl語句
1 使用PreparedStatement, 沒有使用封裝和使用封裝的方法進行實現
package day_19; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; /* SQL 的date()需要傳入引數值: preparedStatement().setDate(new java.util.Date().getTime()); */ /**PreparedStatement 優勢:減輕sql語句的大量書寫, * 1/是Statement的子介面,可以使用其所有方法 * 2/可以傳入帶佔位符的SQL語句,並且提供了補充佔位符變數的方法. * 3/可以有效地防止SQL注入! * 4/提高效能,使用一次就編譯好了sql母句,節省時間; * -------------------- * //1.建立PreparedStatement,建立同時傳入一個sql * String sql="insert into examstudent values(?,?,?)"; * //2.呼叫PreparedStatement 的setXXX(int index,Object val)設定佔位符的值, * Index從1開始, * //3.使用方法執行SQL語句: 執行 查詢 或者 升級 : executeQuery() 或executeUpdate() * //因此,省略了SQl語句*/ public class testPreparedStatement { @Test //使用封裝進JDBCTools的update_sql(sql,args1)的方法進行測試;最後直接進行preparedStatement.executeUpdate(); public void test1(){ String sql="insert into author(id,author_name,nation,second_nation) " + "values(?,?,?,?)"; Object args1[]=new Object[]{4,"劉慈欣","北京","河北"}; Object args2[]=new Object[]{5,"瑞","元星","阿斯加特"}; JDBCTools.update_sql(sql,args1); JDBCTools.update_sql(sql,args2); } //沒有使用封裝的方法進行 public void test2(){ Connection connection=null; PreparedStatement preparedStatement=null; try { connection=JDBCTools.getConnection(); String sql="insert into author(id,author_name,nation) " + "values(?,?,?,?)"; preparedStatement =connection.prepareStatement(sql); preparedStatement.setInt(1, 3); preparedStatement.setString(2, "山楓葉紛飛233"); preparedStatement.setString(3, "中國"); //執行Update更新語句 preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.release(null,preparedStatement,connection); } } }
2 JDBC的工具類
package day_19; import java.io.InputStream; import java.sql.*; import java.util.Properties; /**操縱JDBC的工具類,其中封裝了一些工具方法 * Version 1 : getConnection() : 通過讀取配置檔案從資料庫伺服器獲取一個連線; * Version 2 : release() : 關閉資料庫資源的ResultSet/Statement/Statement * Version 3 : update_sql() : 新增preparedStatement的select的sql的方法 * Version 4: query_sql() : 執行preparedStatement的的查詢操作! */ public class JDBCTools { /*** 執行sql 語句,使用Preparedstatement * @param sql * @param args */ public static void update_sql(String sql,Object...args){//新增preparedStatement的update更新sql的方法,同理可以實現 : 增刪改 Connection connection=null; PreparedStatement preparedStatement=null; try { connection = JDBCTools.getConnection(); preparedStatement=connection.prepareStatement(sql); for(int i=0;i<args.length;i++){ preparedStatement.setObject(i+1, args[i]); } preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { release(null,preparedStatement ,connection); } } //新增preparedStatement的select的sql的方法 public static void query_sql(String sql,Object...args){//執行preparedStatement的的查詢操作! Connection connection=null; PreparedStatement preparedStatement=null; try { connection = JDBCTools.getConnection(); preparedStatement=connection.prepareStatement(sql); for(int i=0;i<args.length;i++){ preparedStatement.setObject(i+1, args[i]); } ResultSet resultSet=null; resultSet=preparedStatement.executeQuery();//執行查詢操作! if(resultSet.next()) System.out.println("RsultSet查詢已經就緒!"); else System.out.println("資料表為空或者404!"); } catch (Exception e) { e.printStackTrace(); } finally { release(null,preparedStatement ,connection); } } public static void release(ResultSet rs,Statement statement, Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement!=null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e2) { e2.printStackTrace(); } } } public static Connection getConnection() throws Exception{ //1.準備資料庫的連線的四個字串 String driverClass=null,jdbcUrl=null,user=null,password=null; //jdbc:mysql:///books ;也可以將localhost省略掉! //2.讀取類路徑下的jdbc.properties 檔案 InputStream in= JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties"); Properties properties =new Properties(); properties.load(in); driverClass =properties.getProperty("driver"); jdbcUrl=properties.getProperty("jdbcUrl"); user = properties.getProperty("user"); password = properties.getProperty("password"); //3.載入資料庫驅動程式(註冊驅動),driver對應的實現類中有註冊驅動的靜態程式碼塊 // Class.forName(driverClass); // //或這麼手動載入,也可以註冊多個數據庫連線的程式碼塊 //DriverManager.registerDriver( Class.forName(driverClass).newInstance()); //4.通過DriverManager 的getConnection()方法獲取資料庫連線。 Connection connection=DriverManager.getConnection(jdbcUrl,user,password); System.out.print(connection); //[email protected] return connection; } }
3 testSQLInjection
package day_19; import org.junit.Test; import javax.swing.text.DocumentFilter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class testSQLInjection { /**使用 * */ @Test //因為匹配結果恆真,就可以進行SQL注入!使用PreparedStatement可以避免這個問題! public void testSQLInjection(){ String username = "a' OR PASSWORD = "; String password = " OR '1'='1"; String sql = "SELECT * FROM users WHERE username = '" + username + "' AND " + "password = '" + password + "'"; System.out.println(sql); Connection connection=null; Statement statement=null; ResultSet resultSet=null; try { connection=JDBCTools.getConnection(); statement=connection.createStatement(); resultSet=statement.executeQuery(sql); if(resultSet.next()) System.out.println("登陸成功!"); else System.out.println("404 ! "); /*******/ System.out.println("PreparedStatement測試結果為:"); String sql2 = "SELECT * FROM users WHERE username = ? AND password = ?"; JDBCTools.query_sql(sql2,username,password); } catch (Exception e) { e.printStackTrace(); } finally { JDBCTools.release(resultSet, statement,connection ); } } }