[1]jdbc的概念
-
什麼是jdbc
JDBC(Java DataBase Connectivity)就是Java資料庫連接配接,說白了就是用Java語言來操作資料庫。原來我們操作資料庫是在控制台使用SQL語句來操作資料庫,JDBC是用Java語言向資料庫發送SQL語句。
- 圖例:
- jdbc的由來
- 早期SUN公司的天才們想編寫一套可以連接配接天下所有資料庫的API,但是當他們剛剛開始時就發現這是不可完成的任務,因為各個廠商的資料庫伺服器差異太大了。後來SUN開始與資料庫廠商們讨論,最終得出的結論是,由SUN提供一套通路資料庫的規範(就是一組接口),并提供連接配接資料庫的協定标準,然後各個資料庫廠商會遵循SUN的規範提供一套通路自己公司的資料庫伺服器的API出現。SUN提供的規範命名為JDBC,而各個廠商提供的,遵循JDBC規範的,可以通路自己資料庫的API被稱之為驅動!
- JDBC是接口,而JDBC驅動才是接口的實作,沒有驅動無法完成資料庫連接配接!每個資料庫廠商都有自己的驅動,用來連接配接自己公司的資料庫。當然還有第三方公司專門為某一資料庫提供驅動,這樣的驅動往往不是開源免費的!
- 總的來說,大緻分為以下四個階段:
-
1:JDBC-ODBC橋接階段 :Java-ODBC-DB
使用odbc,橋接通路資料庫
java剛出名,缺少通路資料庫的方式,sun公司找資料庫廠商提供,廠商未提供,采用中轉方案,使用用為c語言編寫的odbc技術來通路資料庫。
-
2:Native階段:Java-JDBC-Client-DB
使用資料庫廠商提供的實作通路資料庫
Java出名一段時間了,sun公司又找資料庫廠商提供,廠商提供了一套自己實作的jdbc-client,用與通路資料庫。
-
3:JDBC-net pure java drvier: client-general protocol-server-DB
Java通過通路容器服務,去擷取資料庫連接配接,進而通路資料庫
Java更出名了,由于出現了資料庫遷移的需求,例如sqlserver轉oracle,由于jdbc-client的差異,導緻遷移問題,于是sun公司出了一套jdbc通路資料庫的接口,統一了各個廠商之間的jdbc-client底層代碼實作差異。
-
4:native protocal pure java:java-JDBC-DB
jdbc的持續更新,可以通過java程式去找資料庫驅動,然後來連接配接資料庫
-
- jdbc包含的内容
- 接口部分:sun公司提供,在jdk的
和java.sql.*
包中,例:javax.sql.*
class java.sql.DriverManager 管理多個資料庫驅動類,提供了擷取資料庫連接配接的方法。 interface java.sql.Connection 代表一個資料庫連接配接(當Connection對象不為null時,代表已經連接配接上了資料庫)。 interface java.sql.Statement 發送SQL語句到資料庫的工具。 interface java.sql.PreparedStatement Statement的子類,對其進行了封裝,可以處理帶占位符的sql語句,解決了sql注入的問題 interface java.sql.ResultSet 儲存SQL查詢語句的結果資料(結果集)。 - DriverManger(驅動管理器)的作用有兩個:
- 注冊驅動:這可以讓JDBC知道要使用的是哪個驅動;
- 擷取Connection:如果可以擷取到Connection,那麼說明已經與資料庫連接配接上了。
- Connection對象表示連接配接,與資料庫的通訊都是通過這個對象展開的:
- Connection最為重要的一個方法就是用來擷取Statement對象;
- Statement是用來向資料庫發送SQL語句的,這樣資料庫就會執行發送過來的SQL語句
- void executeUpdate(String sql):執行更新操作(insert、update、delete等);
- ResultSet executeQuery(String sql):執行查詢操作,資料庫在執行查詢後會把查詢結果,查詢結果就是ResultSet;
- ResultSet對象表示查詢結果集,隻有在執行查詢操作後才會有結果集的産生。結果集是一個二維的表格,有行有列。操作結果集要學習移動ResultSet内部的“行光标”,以及擷取目前行上的每一列上的資料:
- boolean next():使“行光标”移動到下一行,并傳回移動後的行是否存在;
- XXX getXXX(int col):擷取目前行指定列上的值,參數就是列數,列數從1開始,而不是0。
- 接口部分:sun公司提供,在jdk的
- 實作部分:由資料庫廠商提供,例oracle
- ojdbc14 jdk1.4編寫
- ojdbc5 jdk1.5編寫
- ojdbc6 jdk1.6編寫
[2]jdbc開發步驟[重點]
我使用的Ecllipse,需要建立一個普通的java project
-
注冊驅動
I. 将Oracle資料庫驅動
ojdbc14.jar
複制到項目的lib檔案夾中。
II.
ojdbc14.jar
右鍵 -> build path -> add to build path。
III.
//手動加載位元組碼檔案到JVM中。Class.forName("oracle.jdbc.OracleDriver");
- 擷取連接配接
-
擷取連接配接需要兩步,一是使用DriverManager來注冊驅動,二是使用DriverManager來擷取Connection對象。
擷取連接配接的也隻有一句代碼:
DriverManager.getConnection(url,username,password),
- 通過DriverManager擷取資料庫連接配接對象(Connection),指定三個參數,如下所示:
url:jdbc:oracle:thin:@192.168.230.10:1521:orcl username:username password:password
-
-
獲得發送SQL的工具:
I. 編寫即将執行的SQL語句(語句中不能包含分号)。
II. 通過Connection建立Statement對象。例:
III. Statement是用來向資料庫發送要執行的SQL語句的!Statement stm = con.createStatement();
-
發送sql并接收執行結果
I. DML語句:增删改時,傳回受影響行數(int類型)。
II. DQL語句:查詢時,傳回結果資料(ResultSet結果集)。
-
處理結果
I. DML:增删改時,傳回受影響行數(int類型)。
II. DQL:查詢時,傳回結果集(ResultSet類型)。
-
釋放資源
I. 遵循先開後關。
II. Connection、PreparedStatement、ResultSet。
[3]ResultSet(結果集)【重點】:
- 作用:存儲查詢到的結果資料。
- 使用:
ResultSet rs = stat.executeQuery(sql);
- 獲得ResultSet中的資料:
-
資料行指針:
初始位置在第一行資料前,每調用一次boolean next()方法,傳回為true,則ResultSet的指針向下移動一位
-
ResultSet的API:
rs.next() //判斷是否存在下一行
rs.getXXX(columnIndex) //列的編号(從1開始)
rs.getXXX(columnLabel) //列的名稱
[4]PreparedStatement【重點】:
- 概念:預編譯SQL命名對象
- 參數化SQL:可通過" ? "進行參數的占位
String sql = "select * from t_account where cardId = ? and password = ?";
-
綁定動态參數:
ps.setInt(1,值);
ps.setDouble(2,值);
ps.setString(3,值);
ps.setDate(4,值);
ps.setObject(5,值); //通用
-
發送綁定參數到資料庫執行SQL:
I. int ps.executeUpdate(); //執行增删改
II. ResultSet ps.executeQuery(); //執行查詢
-
PreparedStatement的好處:
I. 作用:發送預編譯的SQL語句。
II. 優勢:防止SQL注入攻擊,執行多個同構SQL的效率高。
III. 計算通路計劃(Access Plan)等效于Oracle的Map集合,将SQL語句一起緩存到記憶體中。//首次通路相對耗時 SQL = key/plan = value
IV. 通過SQL語句查找Oracle緩存通路計劃并執行。
[5]jdbc常見錯誤
類名錯誤 | |
---|---|
URL錯誤 | |
服務沒開 | |
Listener服務沒開 | |
動态參數個數與占位符個數不比對 | |
書寫了小于零,或大于占位符個數的值 |