1. 程式人生 > >JDBC要點總結、SQL注入示例(Statement和PreparedStatement)

JDBC要點總結、SQL注入示例(Statement和PreparedStatement)

寫在前面:JDBC是sun公司(已被Oracle收購)制定一系列介面標準,由不同廠商(Oracle、MySQL等)實現介面方法並封裝成驅動檔案,供開發人員操作資料庫。也就是說,開發人員可採用統一的程式碼

一、三個重要物件:

   a.Connection

  代表著Java程式與資料庫建立的連線。

   b.Statement

  代表SQL傳送器,用於傳送和執行SQL語句。

   c.ResultSet

  代表封裝的資料庫返回的結果集,用於獲取查詢結果。


二、程式設計步驟:

         1、載入驅動(需要事先將驅動程式對應的jar檔案放到classpath對應的路徑)

         驅動:就是不同的資料庫廠商實現的API。Class.forName(驅動類名);

         2、獲得連線。Connection conn = DriverManager.getConnection(url,user,pwd);

         3、獲得Statement。Statment stat = conn.creatStatement();

         4、執行SQL。

                   a.執行查詢:ResultSet rst = stat.executeQuery(SQL);

                   b.執行刪除、更新、插入:int = stat.executeUpdate(SQL);

         5、如果是查詢,需要遍歷ResultSet

                   遍歷:將查詢的結果一條條取出來,獲取其中的資料

         6、關閉連線

三、示例:

mysql簡單使用:

(1)登入MySQL(使用root使用者):mysql -uroot;

(2)檢視資料庫:show databases;

(3)建立資料庫(設定預設字符集utf-8):create database test1 default character set utf8;

(4)使用某個資料庫:use test1;

(5)檢視當前資料庫有哪些表:show tables;

(6)建表:

         create table t_user(

                   id int primary key auto_increment,

                   username varchar(50),

                   pwd varchar(30),

                   age int

         )type=innodb;

         insert into t_user(username,pwd,age)values('jetty','test',23);

         注意:

         auto_increment:自增長列,該列由資料庫自動賦值,一般用於主鍵生成

         type=innodb;表示該表支援事務(常用於大型資料庫)


程式訪問:

public class TestJdbc {

	static String driver = "com.mysql.jdbc.Driver";
	static String url = "jdbc:mysql://localhost:3306/test1";
	static String dbUser = "root";
	static String dbPwd = "111111";

	public static void main(String[] args) throws Exception {
		// findUsers1("jetty", "test");
		findUsers1("sadfas", "1' or '1'='1");//錯誤驗證依然可以獲取使用者資訊,出現SQL注入
		findUsers2("tom", "tompwd");
	}

	/**
	 * 使用原始Statement(容易出現SQL注入)
	 * 
	 * @param username
	 * @param pwd
	 * @throws Exception
	 */
	public static void findUsers1(String username, String pwd) throws Exception {
		// 1.載入類
		Class.forName(driver);
		// 2.獲取連線
		Connection conn = DriverManager.getConnection(url, dbUser, dbPwd);
		System.out.println(conn);
		// 3.獲得Statement
		Statement state = conn.createStatement();
		// 4.呼叫Statement的方法執行SQL
		String sql = "select * from t_user where username = " + "'" + username
				+ "'" + " and pwd = '" + pwd + "'";
		// 5.execute()將SQL語句傳送給資料庫,資料庫執行查詢,資料庫執行相應查詢,查詢的結果會封裝到ResultSet物件。
		ResultSet rst = state.executeQuery(sql);
		// 可以將ResultSet看成一張表,next()含義是,將指標向下移動一位,如果返回值為true,表示當前有記錄可以讀取
		while (rst.next()) {
			int id = rst.getInt("id");
			String name = rst.getString("username");
			String realPwd = rst.getString("pwd");
			int age = rst.getInt("age");
			System.out.println("id:" + id + ",username:" + name + ",realPwd:"
					+ realPwd + ",age:" + age);
		}
		// 6.關閉資源,一般只需關閉連線即可
		if (rst != null) {
			rst.close();
		}
		if (state != null) {
			state.close();
		}
		if (conn != null) {
			conn.close();
		}
	}

	/**
	 * 使用PreparedStatement
	 * 
	 * @param username
	 * @param pwd
	 * @throws Exception
	 */
	public static void findUsers2(String username, String pwd) throws Exception {
		Class.forName(driver);
		Connection conn = DriverManager.getConnection(url, dbUser, dbPwd);
		// sql表示一個佔位符
		String sql = "select * from t_user where username=? and pwd=?";
		PreparedStatement prep = conn.prepareStatement(sql);
		prep.setString(1, username);
		prep.setString(2, pwd);
		ResultSet rst = prep.executeQuery();
		while (rst.next()) {
			int id = rst.getInt("id");
			int age = rst.getInt("age");
			System.out.println("id:" + id + ",age:" + age);
		}
		// 6.關閉資源,一般只需關閉連線即可
		if (rst != null) {
			rst.close();
		}
		if (prep != null) {
			prep.close();
		}
		if (conn != null) {
			conn.close();
		}
	}

}

執行結果:

[email protected]
id:1,username:jetty,realPwd:test,age:23
id:2,username:tom,realPwd:tompwd,age:26
id:2,age:26

四、Statement和PreparedStatement

PrepareStatement和Statement區別和聯絡
--PrepareStatement從Statement繼承
--都是用於傳送和執行SQL語句的
--PrepareStatement是一種預編譯的Statement物件。
  Statement物件是在executeUpdate或executeQuery方法時指定sql,此時將sql語句傳送和執行。
  PrepareStatement物件是在建立時指定併發送sql,在executeUpdate或executeQuery方法時觸發sql執行。

使用原有Statement有以下問題:
--容易遭受注入式攻擊
--拼寫SQL繁瑣和麻煩
通過PrepareStatement可以解決上述問題

PrepareStatement使用步驟:
--編寫帶?號的sql
--利用con.prepareStatement(sql);方法獲取PrepareStatement物件
--利用setXXX()方法給sql的?設定引數值
--呼叫無參的executeUpdate()或executeQuery()執行sql.

圖示:


總結:如圖所示,PrepareStatement是一個預編譯的Statement,將帶佔位符?的SQL語句傳送給資料庫後,SQL語句不會立即執行,資料庫會生成一個執行計劃,此時SQL語句結構已確定,不可更改注入,然後利用setXXX()方法給sql的?設定引數值,傳參後即執行計劃,返回結果集。另外,由於執行計劃已生成,只要傳入引數就可執行計劃,這在大批量存入資料時,編碼更簡單,效率更高。


五、JDBC批處理的使用

 用於處理批量的增刪改操作。可一次向資料庫端傳送多條SQL命令,資料庫可以對這些SQL命令批量編譯執行。
從而提升了批量操作的效能。
  1)Statement
   Statement stat = ...;
   //將sql放入當前的SQL批次中
   stat.addBatch(sql);
   stat.addBatch(sql1);
   ....
   //傳送和執行batch中的SQL
   stat.executeBatch();
  *2)PrepareStatement
   //傳送指定sql語句給資料庫
   //資料庫進行預編譯
   PrepareStatement pst = ...;
  pst.setxxx();//設定?引數值
   //將當前一組引數放入batch快取
  pst.addBatch();
  pst.setxxx();
  pst.addBatch();//將引數放入batch
  //執行批處理
  pst.executeBatch();

  提示:batch中存放的sql語句或運算元不要太多,需要根據機器效能決定,一般採用20個即可。

  示例:

public void saveUsers(List<User> users) throws Exception {
		try {
			conn = DBUtil.getConnection();
			stat = conn
					.prepareStatement("insert into t_user(username,pwd,age)values(?,?,?)");
			for (int i = 0; i < users.size(); i++) {
				User user = users.get(i);
				stat.setString(1, user.getUsername());
				stat.setString(2, user.getPwd());
				stat.setInt(3, user.getAge());
				// stat.executeUpdate();
				stat.addBatch();// 引數先不傳送,先儲存下來
			}
			stat.executeBatch();// 一次性發送所有儲存的引數到資料庫執行
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBUtil.close(conn);
		}
}

常用方法:

addBatch():新增一條要執行的sql。

executeBatch():執行之前新增的所有sql。

clearBatch():清空之前快取過的sql內容。(可不寫,會自動清空)

轉載請註明出處:http://blog.csdn.net/daijin888888/article/details/50965232

相關推薦

JDBC要點總結SQL注入示例StatementPreparedStatement

寫在前面:JDBC是sun公司(已被Oracle收購)制定一系列介面標準,由不同廠商(Oracle、MySQL等)實現介面方法並封裝成驅動檔案,供開發人員操作資料庫。也就是說,開發人員可採用統一的程式碼 一、三個重要物件:    a.Connection   代表著Jav

Spring Boot文件上傳示例AjaxREST

模型 custom rop null nds con and 程序 docs 本文介紹如何使用Ajax請求在Spring Boot Web應用程序(REST結構)中上傳文件。 本文中使用的工具: Spring Boot 1.4.3.RELEASE Spring 4.3.5

Nodejs學習筆記十一—數據采集器示例requestcheerio

列表 意思 9.1 很多 AD 開發 com http undefined 寫在之前   很多人都有做數據采集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是發送各類請求和正則解析數據比較繁瑣些,總體來說沒啥不好的,就是效率要差一些,   用nodej

sublime3使用:自定義快捷鍵外掛安裝語法校驗cssjs

1.快捷鍵大全: https://mp.csdn.net/postedit/84336764 2.新增快捷鍵: 例:ctrl+q 開啟sublime編輯器 preference>>key bindings-user>>編輯設定文件, 輸入 { "key

SQL轉換函式CAST CONVERT

                如果 SQL Server 2005 沒有自動執行資料型別的轉換,可以使用 CAST 和 CONVERT 轉換函式將一種資料型別的表示式轉換為另一種資料型別的表示式。例如,如果比較 char 和 datetime 表示式、smallint 和 int 表示式或不同長度的 cha

Nodejs學習筆記十一--- 資料採集器示例requestcheerio

目錄 寫在之前   很多人都有做資料採集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是傳送各類請求和正則解析資料比較繁瑣些,總體來說沒啥不好的,就是效率要差一些,   用nodejs寫採集程式還是比較有效率(可能也只是相對C#來說),今天主要用一個示例來說一下使用node

JDBC簡單使用工具類構建以及StatementPreparedStatement區別

先來 訪問 結構 puts pla line null tar public 相關源碼會在每一個部分的末尾給出 相關表的結構: 在介紹具體的工具類之前,先來簡單介紹一下JDBC的連接步驟: 1. 註冊驅動 在註冊驅動以前,你需要先導入mysql-co

Redtiger SQL注入練習

感覺會的東西太少了,以後要多練習,多寫部落格。要堅持學習,一定不能放棄,為夢想奮鬥。 redtiger  這個平臺早就開始做了,但是才做到第4關。。。。 第一關: 開啟題, 先隨便試,後來發現點選 Category 後的1 可以注入, 然後就是注入了,構造cat=1'' 還報錯,估

Redtiger SQL注入練習

第六關: 點選 click me,構造url:user=1',返回user not found。user=1'',同樣。 猜測是數字型注入,構造order by , user=1 order by  X#,得出有5個欄位。 然後,user=0 union select 1,2,3,4,5#,說

SQL優化理論基礎:MySQL架構總覽查詢執行流程SQL解析順序轉載

前言:   一直是想知道一條SQL語句是怎麼被執行的,它執行的順序是怎樣的,然後檢視總結各方資料,就有了下面這一篇博文了。   本文將從MySQL總體架構--->

SQL注入技巧拓展】————3SQL注入防禦與繞過的幾種姿勢

本文章主要以後端PHP和MySQL資料庫為例,參考了多篇文章後的集合性文章。 前言 本文章主要以後端PHP和MySQL資料庫為例,參考了多篇文章後的集合性文章,歡迎大家提出個人見解,互促成長。 一、 PHP幾種防禦姿勢 1. 關閉錯誤提示 說明:PHP配置檔案php.ini

安全防禦之防xssSQL注入與CSRF攻擊

XSS攻擊 個人理解,專案中最普通的就是通過輸入框表單,提交js程式碼,進行攻擊例如在輸入框中提交 <script>alert("我是xss攻擊");</script>,如果沒有防御措施的話,就會在表單提交之後,彈出彈窗 防禦措施,目前我主要是用一個過濾器,將特殊字元進行轉

Web站點如何防範XSSCSRFSQL注入攻擊

XSS跨站指令碼攻擊 XSS跨站指令碼攻擊指攻擊者在網頁中嵌入客戶端指令碼(例如JavaScript),當用戶瀏覽此網頁時,指令碼就會在使用者的瀏覽器上執行,從而達到攻擊者的目的,比如獲取使用者

SQL注入教程——寬位元組注入

前言 在mysql中,用於轉義(即在字串中的符號前加上”\”)的函式有addslashes,mysql_real_escape_string,mysql_escape_string等,還有一種情況是magic_quote_gpc,不過高版本的PHP將去除這個特

java面試題精解1:詳解XSS攻擊SQL注入攻擊CSRF攻擊

1、xss攻擊 1.1 什麼是xss攻擊 XSS全稱cross-site scripting(跨站點指令碼),是當前 web 應用中最危險和最普遍的漏洞之一。攻擊者向網頁中注入惡意指令碼,當用戶瀏覽網頁時,指令碼就會執行,進而影響使用者,比如關不完的

Python實戰編寫Burp “sql注入”外掛

    前言:上一篇文章(利用python開發Burp Suite外掛 https://blog.csdn.net/xuandao_ahfengren/article/details/85109223) 簡單介紹瞭如何配置burpsuite外掛開發環境和burp su

Angular 4.3 HttpClient (Angular訪問 REST Web 服務) 一Http 請求示例Get

連結 開發工具:Visual Studio Code 在Angular 4.3中引入了新的HttpClientModule。 這個新模組可以在@ angular / common / http包中找到,並且可以完全重新實現前一個HttpModule。新的Ht

安全測試-- 告訴你什麼是XSSsql注入?POSTGET的區別

1、使用者許可權測試   (1) 使用者許可權控制   1) 使用者許可權控制主要是對一些有許可權控制的功能進行驗證   2) 使用者A才能進行的操作,B是否能夠進行操作(可通過竄session,將在下面介紹)   3)只能有A條件的使用者才能檢視的頁面,是否B能夠檢視(可

手把手叫你SQL注入攻防PHP語法

閒話不說,直接來! 2.本地測試程式碼: 如果表單提交正確,就列印hello,“username” 否則,列印“404 not found!” <?php require 'conf

SQL增刪改查SQL注入事務

SQL注入: SELECT * FROM user WHERE name=”abcd” and password=”“; 當password設定為1234” or “1”=”1”; SELECT * FROM user WHERE name=”abcd”