JDBC(Java Data Base Connectivity,java數據庫連接)是java數據可連接技術的簡稱,提供連接各種常用數據庫的能力。讓java程序員可以直接通過java程序操作數據。jdbc是標準,它是由類與接口組成,對于程序員只需要知道標準(Connection Statement PreparedStatement ResultSet)不需要了解具體的實現就可以操作數據庫
=====
DriverManager:這是一個實現類,它是一個工廠類,用來生產Driver對象這個類的結構設計模式為工廠方法;
Driver:這是驅動程序對象的接口,它指向一個實實在在的數據庫驅動程序對象,那么這個數據庫驅動是從哪里來的呢?
- DriverManager中有個方法:getDriver(String URL),通過這個方法可以得到驅動程序對象,這個方法是在各個數據庫廠商按JDBC規范設計的數據庫驅動程序包里的類中靜態實現的,也就是在靜態塊中。
Connection:這個接口可以指向一個數據庫連接對象,那么如何得帶這個連接對象呢?
- 是通過DriverManager工廠中的getConnection(String URL)方法得到的
Statement:用于執行靜態的SQL語句的接口,通過Connection中的createStatement方法得到的
ResultSet:用于指向結果集對象的接口,結果集對象是通過Statement中的execute等方法得到的
創建一個關于JDBC項目
1. 導入jar包
2. 注冊驅動
- 反射
- Class.forName("com.mysql.jdbc.Driver");
3. 獲取連接(Connection)
- Connection con = DriverManager.getConnection(String url, String username, String password);
4. 獲取操作sql對象 (Statement)
- Statement st = con.createStatement();
如果要獲取滾動結果集,可以使用createStatement(int, int);
5. 操作sql
- DQL 語句
ResultSet rs = st.executeQuery(String sql); - DML 語句
int row = st.executeUpdate(String sql);
6. 遍歷結果集
- while(rs.next()) {
rs.getInt(int columnIndex);
rs.getString(String columuName);
}
7. 釋放資源
- rs.close();
- st.close();
- con.close();
PreparedStatement
- 怎樣獲取?
PreparedStatement pst = con.prepareStatement(String sql); - 怎樣給占位符“?”賦值
pst.setXxx(int,value); - 執行
pst.executeQuery();
pst.executeUpate();
Statement和PreparedStatement的區別
Statement每次執行sql語句,數據庫都要執行sql語句的編譯,最好用于僅執行一次查詢并返回結果的情形,效率高于PreparedStatement.但存在sql注入風險。PreparedStatement是預編譯執行的。在執行可變參數的一條SQL時,PreparedStatement要比Statement的效率高,因為DBMS預編譯一條SQL當然會比多次編譯一條SQL的效率高。安全性更好,有效防止SQL注入的問題。對于多次重復執行的語句,使用PreparedStatement效率會更高一點。執行SQL語句是可以帶參數的,并支持批量執行SQL。由于采用了Cache機制,則預編譯的語句,就會放在Cache中,下次執行相同的SQL語句時,則可以直接從Cache中取出來。
PreparedStatement: 數據庫會對sql語句進行預編譯,下次執行相同的sql語句時,數據庫端不會再進行預編譯了,而直接用數據庫的緩沖區,提高數據訪問的效率(但盡量采用使用?號的方式傳遞參數),如果sql語句只執行一次,以后不再復用。
從安全性上來看,PreparedStatement是通過?來傳遞參數的,避免了拼sql而出現sql注入的問題,所以安全性較好。
在開發中,推薦使用 PreparedStatement
Statement 接口提供了執行語句和獲取結果的基本方法。PreparedStatement 接口添加了處理 IN 參數的方法;而CallableStatement 添加了處理 OUT 參數的方法,用來調用存儲過程。
CallableStatement
CallableStatement cstmt = con.prepareCall("call getTestData(?, ?)");
cstmt.setInt(1, sc.nextInt());
cstmt.registerOutParameter(2, Types.INTEGER);
cstmt.execute();
int result = cstmt.getInt(2);
什么是SQL注入,怎么防止SQL注入?
SQL注入就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到后臺數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。
那么,如何防止SQL注入?不相信用戶輸入,檢查用戶輸入的合法性;將用戶的登錄名、密碼等數據加密保存;不使用動態拼接sql,可以使用參數化或直接使用存儲過程來執行所有的查詢;不使用管理員權限的數據庫連接,為每個應用創建單獨的、有限的權限連接數據庫用戶。