JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫連接)是java數(shù)據(jù)可連接技術(shù)的簡稱啤握,提供連接各種常用數(shù)據(jù)庫的能力未状。讓java程序員可以直接通過java程序操作數(shù)據(jù)鸭限。jdbc是標(biāo)準(zhǔn)蜕径,它是由類與接口組成,對于程序員只需要知道標(biāo)準(zhǔn)(Connection Statement PreparedStatement ResultSet)不需要了解具體的實現(xiàn)就可以操作數(shù)據(jù)庫
=====
DriverManager:這是一個實現(xiàn)類败京,它是一個工廠類兜喻,用來生產(chǎn)Driver對象這個類的結(jié)構(gòu)設(shè)計模式為工廠方法;
Driver:這是驅(qū)動程序?qū)ο蟮慕涌谏穆螅赶蛞粋€實實在在的數(shù)據(jù)庫驅(qū)動程序?qū)ο笃咏裕敲催@個數(shù)據(jù)庫驅(qū)動是從哪里來的呢?
- DriverManager中有個方法:getDriver(String URL)泛粹,通過這個方法可以得到驅(qū)動程序?qū)ο笏煺。@個方法是在各個數(shù)據(jù)庫廠商按JDBC規(guī)范設(shè)計的數(shù)據(jù)庫驅(qū)動程序包里的類中靜態(tài)實現(xiàn)的,也就是在靜態(tài)塊中晶姊。
Connection:這個接口可以指向一個數(shù)據(jù)庫連接對象扒接,那么如何得帶這個連接對象呢?
- 是通過DriverManager工廠中的getConnection(String URL)方法得到的
Statement:用于執(zhí)行靜態(tài)的SQL語句的接口们衙,通過Connection中的createStatement方法得到的
ResultSet:用于指向結(jié)果集對象的接口钾怔,結(jié)果集對象是通過Statement中的execute等方法得到的
創(chuàng)建一個關(guān)于JDBC項目
1. 導(dǎo)入jar包
2. 注冊驅(qū)動
- 反射
- 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();
如果要獲取滾動結(jié)果集,可以使用createStatement(int, int);
5. 操作sql
- DQL 語句
ResultSet rs = st.executeQuery(String sql); - DML 語句
int row = st.executeUpdate(String sql);
6. 遍歷結(jié)果集
- 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); - 執(zhí)行
pst.executeQuery();
pst.executeUpate();
Statement和PreparedStatement的區(qū)別
Statement每次執(zhí)行sql語句忆蚀,數(shù)據(jù)庫都要執(zhí)行sql語句的編譯矾利,最好用于僅執(zhí)行一次查詢并返回結(jié)果的情形,效率高于PreparedStatement.但存在sql注入風(fēng)險馋袜。PreparedStatement是預(yù)編譯執(zhí)行的男旗。在執(zhí)行可變參數(shù)的一條SQL時,PreparedStatement要比Statement的效率高桃焕,因為DBMS預(yù)編譯一條SQL當(dāng)然會比多次編譯一條SQL的效率高剑肯。安全性更好,有效防止SQL注入的問題观堂。對于多次重復(fù)執(zhí)行的語句让网,使用PreparedStatement效率會更高一點。執(zhí)行SQL語句是可以帶參數(shù)的师痕,并支持批量執(zhí)行SQL溃睹。由于采用了Cache機制,則預(yù)編譯的語句胰坟,就會放在Cache中因篇,下次執(zhí)行相同的SQL語句時,則可以直接從Cache中取出來。
PreparedStatement: 數(shù)據(jù)庫會對sql語句進行預(yù)編譯竞滓,下次執(zhí)行相同的sql語句時咐吼,數(shù)據(jù)庫端不會再進行預(yù)編譯了,而直接用數(shù)據(jù)庫的緩沖區(qū)商佑,提高數(shù)據(jù)訪問的效率(但盡量采用使用锯茄?號的方式傳遞參數(shù)),如果sql語句只執(zhí)行一次茶没,以后不再復(fù)用肌幽。
從安全性上來看,PreparedStatement是通過?來傳遞參數(shù)的抓半,避免了拼sql而出現(xiàn)sql注入的問題喂急,所以安全性較好。
在開發(fā)中笛求,推薦使用 PreparedStatement
Statement 接口提供了執(zhí)行語句和獲取結(jié)果的基本方法廊移。PreparedStatement 接口添加了處理 IN 參數(shù)的方法;而CallableStatement 添加了處理 OUT 參數(shù)的方法涣易,用來調(diào)用存儲過程画机。
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表單提交或輸入域名或頁面請求的查詢字符串,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令响禽。具體來說徒爹,它是利用現(xiàn)有應(yīng)用程序,將(惡意)的SQL命令注入到后臺數(shù)據(jù)庫引擎執(zhí)行的能力芋类,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網(wǎng)站上的數(shù)據(jù)庫隆嗅,而不是按照設(shè)計者意圖去執(zhí)行SQL語句。
那么侯繁,如何防止SQL注入胖喳?不相信用戶輸入,檢查用戶輸入的合法性贮竟;將用戶的登錄名丽焊、密碼等數(shù)據(jù)加密保存;不使用動態(tài)拼接sql咕别,可以使用參數(shù)化或直接使用存儲過程來執(zhí)行所有的查詢技健;不使用管理員權(quán)限的數(shù)據(jù)庫連接,為每個應(yīng)用創(chuàng)建單獨的惰拱、有限的權(quán)限連接數(shù)據(jù)庫用戶雌贱。