MySQL Server 簡介
The materials presented in this web page is provided as is and is used solely for educational purpose. Use at your own risks.Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
請勿轉貼
看其他教材
本文假設你已經安裝了 MySQL Server 5.1.x 版,而且你也依據之前的說明, 建立了使用者 jlu,而且你也為 jlu 建立了一個資料庫 eric,並且在資料庫中, 建立了表格 Product。在下列的步驟中,我們將說明如何利用純 JDBC 驅動程式 來開發 Java 程式以便於對表格 Product 進行增、刪、改、查的動作。 以下文件,我們假設讀者熟析 Java 程式;如果讀者想學習 Java 的物件導向 設計的技巧,我們建議購買作者所寫的 呂瑞麟與陳宜惠著,Java 101: 物件導向程式設計,上奇出版,09/2008 以及其 勘誤表。
- 為了讓 Java 程式(包含 JSP、Java Servlets 等)能夠存取資料庫, 昇陽(Sun) 定義了 JDBC 的介面,而各家的資料庫管理系統可以依據這些介面定義, 開發出其資料庫系統的 JDBC 驅動程式。JDBC 驅動程式又分成四大類,其細節 可以參考 資料處理入門,在本文中,我們只針對 MySQL 提供的純 JDBC 驅動程式來說明。
- 純 JDBC 驅動程式:若要使用純 JDBC 驅動程式,請安裝
MySQL
Connector/J。作者下載的是 5.1.x 版的 ZIP Archive,檔案名稱為
mysql-connector-java-5.1.x.zip。將檔案解壓縮之後,
請在解壓縮的目錄內,將 mysql-connector-java-5.1.x-bin.jar 設定到適當的
環境變數 CLASSPATH 內;如果你的開發環境包含 Tomcat,則我們建議
你將 mysql-connector-java-5.1.x-bin.jar 放置於 tomcat\shared\lib
目錄內。假設 Tomcat 安裝於 e:\tomcat,請將該 jar 檔放置於
tomcat\shared\lib 目錄,並設定適當的環境變數 CLASSPATH。
設定環境變數可以由控制台來完成,或者在"命令提示字元"視窗內輸入:
set CLASSPATH=.;e:\tomcat\shared\lib\mysql-connector-java-5.1.x-bin.jar;%CLASSPATH%
- 開發 JDBC 程式:一般來說,以 Java 語言(含 JSP 和 servlet)來連結資料庫,大多需要完成以下的步驟:
- 利用 Class.forName(驅動程式的名稱); 載入 JDBC 的驅動程式;以 MySQL 的 JDBC 驅動程式的名稱為例,載入的用法為 Class.forName("com.mysql.jdbc.Driver");。每一種驅動程式都有其相對應的名稱,開發人員在使用之前必須先搞清楚。
- 利用 Connection conn = DriverManager.getConnection(資料庫的位置, 帳號名 稱, 密碼); 來產生一個 Java 程式和資料庫之間的連線(也就是 Connection 物件 conn)。 DriverManager.getConnection() 內有三個參數,第一個參數說明程式想要 跟哪一個資料庫連線;同樣的,這個參數的值會因為使用的 JDBC 驅動程式不同而 不同,以我們的範例為例,因為我們使用 MySQL 的 JDBC 驅動程式,而且因為 MySQL 的位置在本機(也就是 127.0.0.1),且因為資料庫的名稱為 "eric", 所以第一個參數值必須為 "jdbc:mysql://127.0.0.1/eric"(其中 jdbc:mysql: 是固定不變的,最後 "//IP 位址/資料庫名稱" 會隨著 MySQL 安裝的 IP 位址以及該 MySQL 上的資料庫名稱的不同而改變)。第二個以及 第三個參數分別為連結該資料庫所需要的"帳號名稱"以及"密碼"。
- 連線完成之後,我們可以開始執行 SQL 的指令了。執行 SQL 指令的方式是先 借由 conn 來產生一個 Statement 的物件,然後再藉由 Statement 的物件來執行 SQL 指令。產生 Statement 物件的方式 為 Statement aStatement = conn.createStatement();,其中 aStatement 即為 Statement 物件的名稱。
- SQL 指令主要執行"增、刪、改、查"四個動作,而這四個動作中只有"查詢"
會回傳一個表格的資料,其他三種都只回傳一個代表執行是否成功的整數。
- 如果 SQL 指令執行"增、刪、改",執行的方式為 aStatement.executeUpdate(SQL指令);,該方法回傳總共被改變的資料筆數。以在 Product 新增一筆編號 5 的產 品為例,我們的程式碼即為 aStatement.executeUpdate("insert into Product values(5,'鍵盤',14.5,2)");;由於只有一筆資料被新增,所以執行後,aStatement.executeUpdate() 會回傳 1。
- 如果 SQL 指令執行"查詢",執行的方式為 aStatement.executeQuery(SQL指令 );,該方法回傳查詢的結果;由於 SQL 查詢的結果也是一個表格,該表格由 Java 的 ResultSet 物件所代表。以查詢整個 Product 的資料為例,我們的程式碼即為 ResultSet rs = aStatement.executeQuery("select * from Product");。
- 如果 SQL 指令是查詢,程式大多會進一步處理該查詢結果,也就是 ResultSet
物件。一個 ResultSet 物件包含兩種資料,一種是該回傳表格的 Metadata(由
ResultSetMetaData 物件所代表;該物件包含總共有幾個欄位、欄位的名稱、
欄位的資料型態等資料),另一種是表格的資料。
- 我們可以經由 ResultSetMetaData rsmeta = rs.getMetaData(); 來 取得 ResultSetMetaData 物件;然後經由 int cols = rsmeta.getColumnCount(); 來取得回傳表格的總欄位數;在得到總欄位數 cols 之後,我們就可以經由一個 簡單的 for 迴圈,將每一個欄位的名稱以及資料型態,經由 rsmeta.getColumnLabel(i) 以及 rsmeta.getColumnType(i)。
- 經由 ResultSet 物件 rs 可以取得實際的查詢資料。在預設的情形下,一開始 rs 指向資料的第 0 筆,我們可以經由 rs.next() 來依序取得下一筆的資料, 一旦下一筆資料不存在,rs.next() 會回傳 false。當 rs.next() 指向某一筆資料的 時候,我們可以利用之前 rsmeta 來取得總欄位數,然後利用 rs.getString(i) 將一個一個欄位的資料以字串的方式取出。除了 getString(i) 的方式之外, 我們也可以利用 getDate(i)、getTime(i)、getDouble(i)、 getInt(i) 等方法分別取出資料型態為 Date、Time、double、int 的資料。
- 最後,但也是很重要的:在程式結束以前,我們必須將相關的資料庫資源釋放 出來。資源釋放的方式是經由呼叫該物件的 close() 方法達成;若釋放 Statement 物件,則與該 Statement 物件相關的 ResultSet 物件也會被釋放。 另外,在程式的最後,我們也必須經由 conn.close(); 將連線釋放。
import java.sql.*; public class NewJDBC { // 設定 JDBC 驅動程式的名稱:com.mysql.jdbc.Driver static String classname = "com.mysql.jdbc.Driver"; // 設定 JDBC 的連線資訊,其中 jdbc:mysql:// 是固定不變的 // 在 // 之後,首先加上 IP 或者主機名稱,在本例中是 127.0.0.1 // IP 之後,請接上斜線(/)以及資料庫的名稱,在本例中是 eric static String jdbcURL = "jdbc:mysql://127.0.0.1/eric"; static String UID = "jlu"; static String PWD = "newpasswd"; static Connection conn = null; public static void main( String argv[] ) { if(argv.length != 1) { System.out.println("Usage: java NewJDBC Product"); System.exit(2); } String aQuery = "select * from " + argv[0]; String iSQL = "insert into " + argv[0] + " values(5,'鍵盤',14.5,2)"; String uSQL = "update " + argv[0] + " set Name='無線鍵盤' where ID=5"; String dSQL = "delete from " + argv[0] + " where ID=5"; try { // 載入 JDBC 驅動程式 Class.forName(classname).newInstance(); // connect to Database conn = DriverManager.getConnection(jdbcURL,UID,PWD); // Display current content System.out.println("Display current content"); ShowResults(aQuery); // Insert a new record System.out.println("\nInserting a new record ....."); InsertNew(iSQL); ShowResults(aQuery); // Update record System.out.println("\nUpdateing a record ....."); UpdateNew(uSQL); ShowResults(aQuery); // Delete record System.out.println("\nDeleting a record ....."); DeleteNew(dSQL); ShowResults(aQuery); conn.close(); } catch (Exception sqle) { System.out.println(sqle); System.exit(1); } } private static void DeleteNew(String dSQL) { try { Statement aStatement = conn.createStatement(); aStatement.executeUpdate(dSQL); } catch (Exception e) { System.out.println("Delete Error: " + e); System.exit(1); } } private static void UpdateNew(String uSQL) { try { Statement aStatement = conn.createStatement(); aStatement.executeUpdate(uSQL); } catch (Exception e) { System.out.println("Update Error: " + e); System.exit(1); } } private static void InsertNew(String iSQL) { try { Statement aStatement = conn.createStatement(); aStatement.executeUpdate(iSQL); } catch (Exception e) { System.out.println("Insert Error: " + e); System.exit(1); } } private static void ShowResults(String aQuery) { try { Statement aStatement = conn.createStatement(); ResultSet rs = aStatement.executeQuery(aQuery); ResultSetMetaData rsmeta = rs.getMetaData(); int cols = rsmeta.getColumnCount(); // Display column headers for(int i=1; i<=cols; i++) { if(i > 1) System.out.print("\t"); System.out.print(rsmeta.getColumnLabel(i)); } System.out.print("\n"); // Display query results. while(rs.next()) { for(int i=1; i<=cols; i++) { if (i > 1) System.out.print("\t"); System.out.print(rs.getString(i)); } System.out.print("\n"); } // Clean up aStatement.close(); } // a better exception handling can be used here. catch (Exception e) { System.out.println("Exception Occurs."); } } }
Written by: 國立中興大學資管系呂瑞麟 Eric Jui-Lin Lu
沒有留言:
張貼留言