JDBC是使用Java存取數據庫系統的標准解決方案,它將不同數據庫間各自差異API與標准SQL語句分開看待,實現數據庫無關的Java操作接口。對於開發人員而言,使用JDBC統一的API接口,專注於標准SQL 語句,就可以避免直接處理底層數據庫驅動程序與相關操作接口的差異性,而將主要精力投放於應用開發本身,從而加快開發進度。
1.JDBC的API接口
JDBC規范采用接口和實現分離的思想,設計了Java數據庫編程的框架。JDBC的API提供了一組標准的Java語言中的接口和類,使用這些接口和類,Java客戶端程序可以訪問各種不同類型的數據庫。如圖1所示。
圖1 JDBC工作原理示意圖
其中,JDBC API由sun公司提供,定義與數據庫建立連接、執行SQL語句、處理結果的方法,這些供程序員調用的接口與類,集成在java.sql和javax.sql包中。DriverManager類的作用是載入各種不同的JDBC驅動程序。而各種數據庫的JDBC驅動程序則由不同的數據庫廠商提供,用於針對具體的數據庫產品實現JDBC API中的方法。
在JDBC的API中主要提供了以下一些接口和類:Connection、DriverManager、Statement、 ResultSet、PreparedStatement、CallableStatement。
其中,Connection對象代表與數據庫的連接。連接過程包括所執行的SQL語句和在該連接上所返回的結果。一個應用程序可與單個數據庫有一個或多個連接,或者可與許多數據庫有連接。
DriverManager類是JDBC 的管理層,作用於用戶和驅動程序之間。它跟蹤可用的驅動程序,並在數據庫和相應驅動程序之間建立連接。
Statement對象用於將SQL語句發送到數據庫中。實際上有三種Statement 對象,它們都作為在給定連接上執行SQL語句的包容器:Statement、PreparedStatement和 CallableStatement。
ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法(這些get方法可以訪問當前行中的不同列)提供了對這些行中數據的訪問。
PreparedStatement實例包含已編譯的SQL語句。包含於 PreparedStatement 對象中的SQL語句可具有一個或多個參數。
CallableStatement對象為所有的DBMS提供了一種以標准形式調用已儲存過程的方法。已儲存過程儲存在數據庫中。對已儲存過程的調用是CallableStatement對象所含的內容。
關於JDBC API的詳細敘述可以參見《Java數據庫接口JDBC入門基礎講座 》(http://www.yesky.com/zhuanti/443/1865943.shtml),講解的非常詳細。
2.環境搭建
下面簡單講講如何安裝MySQL數據庫和Navicat for MySQL工具。
MySQL數據庫的下載和安裝可以參見《MySQL安裝圖解》(http://www.jb51.net/article/23876.htm),這里就不再贅述了。
Navicat for MySQL是基於Windows平台,為MySQL數據庫量身訂作的類似於MySQL的用戶管理界面工具。使用了圖形用戶界面(GUI),可以用一種安全和更為容易的方式快速地創建、組織、存取和共享數據。
Navicat for MySQL的下載地址為:http://www.cr173.com/soft/26935.html
Navicat for MySQL的安裝和使用可以參見《Navicat MySQL安裝及使用說明》(http://wenku.baidu.com/view/6938c04b2b160b4e767fcf6b.html),這里也不再贅述了。
運行Navicat for MySQL工具,創建一個連接到我們所安裝的MySQL數據庫的連接,這里我創建的連接名為“myConnection”。打開該連接,並創建一個數據庫,這里我創建了一個名為“mydb”的數據庫。在該數據庫中,我們創建了一張名為“userinfo”的表。
做好這一切之后,我們就可以對這張表進行設計了,設計的目的在於指定數據的儲存結構。這這張表中我們存儲了id、username、password三項內容。設計好的表如圖2所示。
圖2 表的設計
3.使用JDBC訪問MySQL數據庫
使用JDBC訪問數據庫的一般步驟如下:
3.1加載JDBC驅動程序
不同的數據庫對應着不同的驅動程序,要使用JDBC API訪問MySQL數據庫,需要在工程的libs目錄下導入MySQL數據庫的驅動包mysql-connector-java-5.1.7-bin。
不同數據庫廠商的驅動類名不同,具體為:
Oracle10g:oracle.jdbc.driver.OracleDriver
MySQL5:com.mysql.jdbc.Driver
SQLServer2005:com.microsoft.sqlserver.jdbc.SQLServerDriver
3.2提供連接參數
不同數據庫產品的連接URL不同,具體為:
Oracle10g:jdbc:oracle:thin:@主機名:端口:數據庫SID
比如:jdbc:oracle:thin:@localhost:1521:ORCL
MySQL5:jdbc:mysql://主機名:端口/數據庫名
比如:jdbc:mysql://localhost:3306/test
SQLServer2005:jdbc:sqlserver://主機名:端口:DatabaseName=庫名
比如:jdbc:sqlserver://localhost:1433:DatabaseName=BookDB
在使用JDBC訪問數據庫時,提供的連接參數除了數據庫的URL之外,還有兩個參數:數據庫的用戶名和數據庫的密碼。
3.3建立一個數據庫的連接
Connection 對象是數據庫連接的具體實例,一個Connection 對象就代表一個數據庫連接,可以使用 DriverManager 的getConneciton()方法傳入指定數據庫的連接URL、用戶名和密碼。
從DriverManager中獲得Connection對象,驅動程序會自動通過DriverManager.registerDriver() 方法注冊,這樣DriverManager就可以跟廠商的驅動程序通信了。
在連接數據庫時,需要檢測異常對象java.sql.SQLException。
建立數據庫連接的具體實現方法如下:
1 private final String USERNAME = "root"; //定義數據庫的用戶名 2 private final String PASSWORD = "******"; //定義數據庫的密碼 3 private final String DRIVER = "com.mysql.jdbc.Driver"; //定義數據庫的驅動信息 4 private final String URL = "jdbc:mysql://localhost:3306/mydb"; //定義訪問數據庫的地址 5 6 /* 7 * Function : 獲取數據庫連接 8 * Author : 博客園-依舊淡然 9 */ 10 public Connection getConnection() { 11 try { 12 mConnection = DriverManager.getConnection(URL, USERNAME, PASSWORD); 13 } catch (Exception e) { 14 System.out.println("連接數據庫失敗!"); 15 } 16 return mConnection; 17 }
3.4創建一個Statement對象
PreparedStatement對象用於執行動態SQL語句。SQL中會變動的部分可以使用?作為參數占位符。
3.5執行SQL語句
對數據庫的常用操作有添加、刪除以及修改。有時我們還需要對數據庫表中的信息進行查詢,這時我們可以使用如下方法來實現:
1 /* 2 * Function : 查詢返回單條記錄 3 * Author : 博客園-依舊淡然 4 */ 5 public Map<String, Object> findSimpleResult(String sql, List<Object> params) 6 throws SQLException { 7 Map<String, Object> map = new HashMap<String, Object>(); 8 int index = 1; 9 mPreparedStatement = mConnection.prepareStatement(sql); 10 if((params != null) && (!params.isEmpty())) { 11 for(int i = 0; i < params.size(); i++) { 12 mPreparedStatement.setObject(index++, params.get(i)); 13 } 14 } 15 mResultSet = mPreparedStatement.executeQuery(); //返回查詢結果 16 ResultSetMetaData resultSetMateData = mResultSet.getMetaData(); //獲得列的相關信息 17 int cols_len = resultSetMateData.getColumnCount(); //獲得列的長度 18 while(mResultSet.next()) { 19 for(int i = 0; i < cols_len; i++) { 20 String cols_name = resultSetMateData.getColumnName(i+1) ; 21 Object cols_value = mResultSet.getObject(cols_name); 22 if(cols_value == null) { 23 cols_value = ""; 24 } 25 map.put(cols_name, cols_value); 26 } 27 } 28 return map; 29 }
3.6處理結果
通過以上幾個步驟已經實現了對數據庫的訪問,在這一步就可以對訪問到的數據進行處理了。
3.7關閉連接
在操作完成后要把所使用的JDBC對象全都關閉,以釋放JDBC資源。具體的實現方法如下:
1 /* 2 * Function : 斷開連接 3 * Author : 博客園-依舊淡然 4 */ 5 public void releaseConnection() { 6 if(mResultSet != null) { //關閉ResultSet對象 7 try { 8 mResultSet.close(); 9 } catch (SQLException e) { 10 e.printStackTrace(); 11 } 12 } 13 if(mPreparedStatement != null) { //關閉PreparedStatement對象 14 try { 15 mPreparedStatement.close(); 16 } catch (SQLException e) { 17 e.printStackTrace(); 18 } 19 } 20 if(mConnection != null) { //關閉Connection對象 21 try { 22 mConnection.close(); 23 } catch (SQLException e) { 24 e.printStackTrace(); 25 } 26 } 27 }