38
11-1 JDBC 11-1 JDBC 的的的 的的的 - - 的的 的的 的的的的的的的的的的的的的體( 的的的的的的的的的的的的的體( Middleware Middleware 的的 的的 JDBC JDBC Java Database Java Database Connectivity Connectivity 的的的 的的的的的的 ),一 的的的 的的的的的的 ),一 Java Java 的的的 的的的 的 的的的 的 的的的 Java Java 的的的的的的的的的的的的 的的的的的的的的的的的的 Java Java 的的的的 的的的的 的的的的 的的的的 JDBC JDBC 的的的的的的 的的的的的的 JDBC Driver Interface JDBC Driver Interface 的的的的 的 ), 的的的的 的 ), JDBC AP JDBC AP JDBC API JDBC API

11-1 JDBC 的基礎 - 說明

  • Upload
    korene

  • View
    64

  • Download
    0

Embed Size (px)

DESCRIPTION

11-1 JDBC 的基礎 - 說明. 昇陽公司提出的資料庫中介軟體( Middleware )稱為「 JDBC 」( Java Database Connectivity ),這是一種開放標準的 Java 程式介面,可以讓 Java 程式連接資料庫管理系統, 以 Java 技術來說,就是實作 JDBC 驅動程式介面( JDBC Driver Interface )的類別,即 JDBC AP 即 JDBC API 。. 11-1 JDBC 的基礎 - 圖例. 11-1 JDBC 的基礎 - 驅動程式種類. - PowerPoint PPT Presentation

Citation preview

Page 1: 11-1 JDBC 的基礎 - 說明

11-1 JDBC11-1 JDBC 的基礎的基礎 -- 說明說明 昇陽公司提出的資料庫中介軟體昇陽公司提出的資料庫中介軟體(( MiddlewareMiddleware )稱為「)稱為「 JDBCJDBC 」(」( Java Java Database ConnectivityDatabase Connectivity ),這是一種開),這是一種開放標準的放標準的 JavaJava 程式介面,可以讓程式介面,可以讓 JavaJava 程程式連接資料庫管理系統,式連接資料庫管理系統,

以以 JavaJava 技術來說,就是實作技術來說,就是實作 JDBCJDBC 驅動程驅動程式介面(式介面( JDBC Driver InterfaceJDBC Driver Interface )的類)的類別,即別,即 JDBC APJDBC AP即即 JDBC APIJDBC API 。。

Page 2: 11-1 JDBC 的基礎 - 說明

11-1 JDBC11-1 JDBC 的基礎的基礎 -- 圖例圖例

Page 3: 11-1 JDBC 的基礎 - 說明

11-1 JDBC11-1 JDBC 的基礎的基礎 -- 驅動程式種驅動程式種類類

JDBC-ODBCJDBC-ODBC橋接驅動程式(橋接驅動程式( JDBC-ODBC BridgJDBC-ODBC Bridgee ):): JavaJava 程式不是直接連接資料庫管理系統,而是透程式不是直接連接資料庫管理系統,而是透過微軟過微軟 ODBCODBC 的中介軟體來存取資料庫。的中介軟體來存取資料庫。

原生原生 APIAPI的的 JavaJava驅動程式(驅動程式( A Native-API Partly A Native-API Partly Java DriverJava Driver ):):將將 JavaJava 程式的程式的 JDBCJDBC 呼叫轉換成專屬呼叫轉換成專屬資料庫管理系統的原生資料庫管理系統的原生 APIAPI 呼叫。呼叫。

JavaJava網路協定驅動程式(網路協定驅動程式( A Net-protocol All Java A Net-protocol All Java DriverDriver ):):將將 JavaJava 程式的程式的 JDBCJDBC 呼叫轉換成資料庫管理呼叫轉換成資料庫管理系統專屬的網路協定,再由伺服器轉換成資料庫管理系統系統專屬的網路協定,再由伺服器轉換成資料庫管理系統的的 APIAPI 呼叫。呼叫。

JavaJava原生通訊協定驅動程式(原生通訊協定驅動程式( A Native-protocol A Native-protocol All Java DriverAll Java Driver ):):將將 JavaJava 程式的程式的 JDBCJDBC 呼叫直接轉呼叫直接轉換成資料庫管理系統原生通訊協定的換成資料庫管理系統原生通訊協定的 APIAPI 呼叫,以便客戶呼叫,以便客戶端直接連線資料庫伺服器。端直接連線資料庫伺服器。

Page 4: 11-1 JDBC 的基礎 - 說明

11-2 11-2 建立建立 MySQLMySQL的資料庫連結的資料庫連結 11-2-1 11-2-1 安裝安裝 MySQLMySQL的的 JDBCJDBC 驅動程式驅動程式 11-2-2 11-2-2 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資料庫資料庫

Page 5: 11-1 JDBC 的基礎 - 說明

11-2-1 11-2-1 安裝安裝 MySQLMySQL的的 JDBCJDBC 驅驅動程式動程式

MySQLMySQL 資料庫系統支援資料庫系統支援 JDBCJDBC的的 JavaJava 原生通訊原生通訊協定驅動程式,稱為協定驅動程式,稱為 MySQL Connector/JMySQL Connector/J ,我,我們可以在們可以在 MySQLMySQL 網站免費下載,目前版本是網站免費下載,目前版本是3.03.0 版,在版,在 JSPJSP的的WebWeb 應用程式安裝應用程式安裝 MySQL MySQL Connector/JConnector/J ,其步驟如下所示:,其步驟如下所示:• 1. 1. 使用解壓縮工具從壓縮檔取出使用解壓縮工具從壓縮檔取出 JARJAR 檔案:檔案:

mysql-connector-java-3.0.16-ga-bin.jarmysql-connector-java-3.0.16-ga-bin.jar 。。• 2. 2. 將將 JARJAR 檔案複製檔案複製 WebWeb 應用程式的「應用程式的「 WEB-WEB-

INF\libINF\lib 」資料夾,以」資料夾,以 Ch11Ch11 應用程式為例,其應用程式為例,其完整路徑為「完整路徑為「 C:\Inetpub\wwwroot\Ch11\C:\Inetpub\wwwroot\Ch11\WEB-INF\libWEB-INF\lib 」。」。

Page 6: 11-1 JDBC 的基礎 - 說明

11-2-2 11-2-2 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫料庫 -- 說說明明

在安裝好在安裝好 MySQLMySQL的的 JDBCJDBC 驅動程式驅動程式後,後, JSPJSP 程式就可以使用程式就可以使用 JDBCJDBC 建立資料建立資料庫連結,然後透過庫連結,然後透過 JDBC APIJDBC API 執行執行 SQLSQL 指指令來存取資料庫的記錄資料。令來存取資料庫的記錄資料。

Page 7: 11-1 JDBC 的基礎 - 說明

11-2-2 11-2-2 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫料庫 -- 步步驟一驟一

步驟一:載入驅動程式步驟一:載入驅動程式 在在 JSPJSP 程式首先需要載入程式首先需要載入 JDBCJDBC 驅動程式,如下驅動程式,如下

所示:所示:String sDriver = "com.mysql.jdbc.Driver";String sDriver = "com.mysql.jdbc.Driver";

Class.forName(sDriver);Class.forName(sDriver); 上述程式碼的字串上述程式碼的字串 sDriversDriver 是驅動程式名稱是驅動程式名稱

com.mysql.jdbc.Drivercom.mysql.jdbc.Driver ,接著使用,接著使用 ClassClass 類別類別方法方法 forName()forName() 方法載入驅動程式。方法載入驅動程式。

Page 8: 11-1 JDBC 的基礎 - 說明

11-2-2 11-2-2 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫料庫 -- 步步驟二驟二

步驟二:建立步驟二:建立 ConnectionConnection 連結物件連結物件 在載入在載入 JDBCJDBC 驅動程式後,就可以使用驅動程式後,就可以使用

DriverManagerDriverManager 類別的類別的getConnection()getConnection() 類別方法建立類別方法建立ConnectionConnection 物件物件 dbCondbCon ,如下所示:,如下所示:

sCon = "jdbc:mysql://localhost:3306/school?sCon = "jdbc:mysql://localhost:3306/school?user=root&password=123456";user=root&password=123456";

dbCon=DriverManager.getConnection(sCon)dbCon=DriverManager.getConnection(sCon);;

Page 9: 11-1 JDBC 的基礎 - 說明

11-2-2 11-2-2 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫料庫 -- 步步驟三驟三

步驟三:建立步驟三:建立 JDBCJDBC的的 StatementStatement 物件物件 StatementStatement 物件的目的是執行物件的目的是執行 SQLSQL 指令,指令,

在建立好在建立好 ConnectionConnection 物件後,就可以使物件後,就可以使用用 createStatement()createStatement() 方法建立方法建立StatementStatement 物件,如下所示:物件,如下所示:

stmt = dbCon.createStatement();stmt = dbCon.createStatement();

Page 10: 11-1 JDBC 的基礎 - 說明

11-3 11-3 建立建立 AccessAccess的資料庫連結的資料庫連結 11-3-1 JDBC-ODBC11-3-1 JDBC-ODBC 資料庫連結的基礎資料庫連結的基礎 11-3-2 11-3-2 建立資料庫與系統資料來源建立資料庫與系統資料來源 11-3-3 11-3-3 使用使用 JDBC-ODBCJDBC-ODBC 連結連結 AccessAccess

資料庫資料庫

Page 11: 11-1 JDBC 的基礎 - 說明

11-3-1 JDBC-ODBC11-3-1 JDBC-ODBC 資料庫連結資料庫連結的基礎的基礎 -- 說明說明

AccessAccess 並不支援並不支援 JDBCJDBC 驅動程式。所以驅動程式。所以JSPJSP 程式需要使用程式需要使用 JDBCJDBC的的 JDBC-ODBCJDBC-ODBC 橋橋接驅動程式,透過接驅動程式,透過 JDBC-ODBCJDBC-ODBC 驅動程式驅動程式存取存取 ODBCODBC 資料來源的資料來源的 AccessAccess 資料庫。資料庫。

「「 ODBCODBC 」(」( Object Database Object Database ConnectivityConnectivity )是微軟開發的中介軟體,)是微軟開發的中介軟體,提供提供 WindowsWindows 作業系統的應用程式一種作業系統的應用程式一種標準的資料庫存取方式,能夠存取位在其標準的資料庫存取方式,能夠存取位在其它電腦上執行的資料庫系統。它電腦上執行的資料庫系統。

Page 12: 11-1 JDBC 的基礎 - 說明

11-3-1 JDBC-ODBC11-3-1 JDBC-ODBC 資料庫連結的資料庫連結的基礎基礎 -- 圖例圖例

Page 13: 11-1 JDBC 的基礎 - 說明

11-3-2 11-3-2 建立資料庫與系統資料建立資料庫與系統資料來源來源 -- 建立建立 AccessAccess 資料庫資料庫

AccessAccess 資料庫是學校資料庫資料庫是學校資料庫 School.mdbSchool.mdb ,在,在School.mdbSchool.mdb 資料庫擁有資料庫擁有 StudentsStudents 資料表,其資料表,其欄位說明,如下表所示:欄位說明,如下表所示:欄位名稱 資料類型 長度

stdno 文字 5

name 文字 12

address 文字 50

birthday 日期/時間 N/A

totalcredit 數字/整數 N/A

Page 14: 11-1 JDBC 的基礎 - 說明

11-3-2 11-3-2 建立資料庫與系統資料來建立資料庫與系統資料來源源 -- 新增新增 ODBCODBC 系統資料來源系統資料來源

在在 AccessAccess 建立好資料建立好資料庫後,就可以在庫後,就可以在WindowsWindows 作業系統建作業系統建立立 ODBCODBC 系統資料來系統資料來源,筆者準備在源,筆者準備在Windows XPWindows XP 作業系作業系統的電腦新增統的電腦新增 AccessAccess資料庫資料庫 School.mdbSchool.mdb名為名為【【 school_dbschool_db 】】的的 ODBCODBC 系統資料來系統資料來源,如右圖所示:源,如右圖所示:

Page 15: 11-1 JDBC 的基礎 - 說明

11-3-3 11-3-3 使用使用 JDBC-ODBCJDBC-ODBC 連結連結AccessAccess 資料庫資料庫 -- 載入驅動程式載入驅動程式

載入載入 JDBC-ODBCJDBC-ODBC 驅動程式驅動程式 在在 JSPJSP 程式載入的驅動程式是透過程式載入的驅動程式是透過 ODBCODBC 存取資存取資

料庫,所以載入料庫,所以載入 JDBC-ODBCJDBC-ODBC 驅動程式,如下所驅動程式,如下所示:示:

String sDriver = String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";"sun.jdbc.odbc.JdbcOdbcDriver";

Class.forName(sDriver);Class.forName(sDriver); 上述程式碼的字串上述程式碼的字串 sDriversDriver 是驅動程式名稱是驅動程式名稱

sun.jdbc.odbc.JdbcOdbcDriversun.jdbc.odbc.JdbcOdbcDriver ,接著載入,接著載入JDBC-ODBCJDBC-ODBC 驅動程式。驅動程式。

Page 16: 11-1 JDBC 的基礎 - 說明

11-3-3 11-3-3 使用使用 JDBC-ODBCJDBC-ODBC 連結連結AccessAccess 資料庫資料庫 -JDBC URL-JDBC URL

JDBC URLJDBC URL 位址字串位址字串 在載入在載入 JDBC-ODBCJDBC-ODBC 驅動程式後,就可以驅動程式後,就可以

使用使用 DriverManagerDriverManager 類別的類別的getConnection()getConnection() 類別方法建立類別方法建立ConnectionConnection 物件物件 dbCondbCon ,如下所示:,如下所示:

String sCon = "jdbc:odbc:school_db";String sCon = "jdbc:odbc:school_db";

dbCon = dbCon = DriverManager.getConnection(sCon);DriverManager.getConnection(sCon);

Page 17: 11-1 JDBC 的基礎 - 說明

範例範例 <!-- JSP<!-- JSP 程式:程式: Ch11_3_3.jsp -->Ch11_3_3.jsp --> <%@ page contentType="text/html; charset=MS950"<%@ page contentType="text/html; charset=MS950" import="java.sql.*"%>import="java.sql.*"%> <html><html> <head><title>Ch11_3_3.jsp</title></head><head><title>Ch11_3_3.jsp</title></head> <body><body> <h2><h2> 建立建立 JDBC-ODBCJDBC-ODBC 資料庫連結資料庫連結 </h2><hr></h2><hr> <%<% Connection dbCon = null; // Connection dbCon = null; // 宣告物件變數宣告物件變數 Statement stmt = null;Statement stmt = null; // // 驅動程式參數驅動程式參數 String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; String sCon = "jdbc:odbc:school_db";String sCon = "jdbc:odbc:school_db"; try {try { // // 載入 載入 JDBC driver JDBC driver Class.forName(sDriver);Class.forName(sDriver); // // 建立資料連結和建立資料連結和 StatementStatement 物件物件 dbCon = DriverManager.getConnection(sCon);dbCon = DriverManager.getConnection(sCon); if ( dbCon != null )if ( dbCon != null ) out.print("out.print(" 建立資料來源連結成功建立資料來源連結成功 !<br>");!<br>"); stmt = dbCon.createStatement();stmt = dbCon.createStatement(); if ( stmt != null )if ( stmt != null ) out.print("out.print(" 建立建立 StatementStatement 物件成功物件成功 !<br>");!<br>"); stmt.close(); // stmt.close(); // 關閉關閉 StatementStatement 物件物件 dbCon.close(); // dbCon.close(); // 關閉連結關閉連結 }} catch(SQLException e) {catch(SQLException e) { out.print(e); out.print(e); }} %>%> </body></body> </html></html>

Page 18: 11-1 JDBC 的基礎 - 說明

11-4 JSP11-4 JSP的資料庫基本存取的資料庫基本存取

11-4-1 11-4-1 取得資料表的資訊取得資料表的資訊 11-4-2 11-4-2 顯示資料表的記錄資料顯示資料表的記錄資料 11-4-3 11-4-3 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資料庫的資料庫的

中文問題中文問題

Page 19: 11-1 JDBC 的基礎 - 說明

11-4-1 11-4-1 取得資料表的資訊取得資料表的資訊 -- 步驟四步驟四 取得資料表資訊是繼續第取得資料表資訊是繼續第 11-2-211-2-2 節的步驟節的步驟

三。三。步驟四:使用步驟四:使用 StatementStatement 物件執行物件執行 SQLSQL 指指

令令 在前面已經說過,建立在前面已經說過,建立 StatementStatement 物件的物件的

目的是執行目的是執行 SQLSQL 指令,如下所示:指令,如下所示:String sSQL="SELECT * FROM students";String sSQL="SELECT * FROM students";

boolean state = stmt.execute(sSQL);boolean state = stmt.execute(sSQL);

Page 20: 11-1 JDBC 的基礎 - 說明

11-4-1 11-4-1 取得資料表的資訊取得資料表的資訊 -- 步驟五步驟五

步驟五:取得步驟五:取得 ResultSetResultSet和和 ResultSetMetaDataResultSetMetaData物件物件

在使用在使用 StatementStatement 物件執行物件執行 SQLSQL 指令後,接著指令後,接著可以使用可以使用 getResultSet()getResultSet() 方法取得方法取得 ResultSetResultSet物件,如下所示:物件,如下所示:

ResultSet rs = stmt.getResultSet();ResultSet rs = stmt.getResultSet(); 上述程式碼在取得上述程式碼在取得 ResultSetResultSet 物件後,再使用物件後,再使用

getMetaData()getMetaData() 方法取得方法取得 ResultSetMetaDataResultSetMetaData物件,如下所示:物件,如下所示:

ResultSetMetaData md = rs.getMetaData();ResultSetMetaData md = rs.getMetaData(); 在取得在取得 ResultSetMetaDataResultSetMetaData 物件後,就可以使物件後,就可以使

用相關方法取得資料表的相關資訊。用相關方法取得資料表的相關資訊。

Page 21: 11-1 JDBC 的基礎 - 說明

11-4-1 11-4-1 取得資料表的資訊取得資料表的資訊 -- 方法方法 ResultSetMetaDataResultSetMetaData 物件的相關方法,如物件的相關方法,如

下表所示:下表所示:方法 說明

int getColumnCount() 取得資料表共有多少欄位int getColumnDisplaySize(int) 取得資料表欄位的尺寸,參數是欄位編

號,從 1開始String getColumnLabel(int) 取得資料表欄位名稱,參數是欄位編號

String getColumnTypeName(int) 取得資料表欄位的資料類型,參數是欄位編號

Page 22: 11-1 JDBC 的基礎 - 說明

範例範例 <!-- JSP<!-- JSP 程式:程式: Ch11_4_1.jsp -->Ch11_4_1.jsp --> <%@ page contentType="text/html; charset=MS950"<%@ page contentType="text/html; charset=MS950" import="java.sql.*"%>import="java.sql.*"%> <html><html> <head><title>Ch11_4_1.jsp</title></head><head><title>Ch11_4_1.jsp</title></head> <body><body> <h2><h2> 取得資料表的資訊取得資料表的資訊 </h2><hr></h2><hr> <%<% Connection dbCon = null; // Connection dbCon = null; // 宣告物件變數宣告物件變數 Statement stmt = null;Statement stmt = null; ResultSet rs = null;ResultSet rs = null; ResultSetMetaData md = null;ResultSetMetaData md = null; // // 驅動程式參數驅動程式參數 String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; String sCon = "jdbc:odbc:school_db";String sCon = "jdbc:odbc:school_db"; try {try { // // 載入 載入 JDBC driver JDBC driver Class.forName(sDriver);Class.forName(sDriver); // // 建立資料連結和建立資料連結和 StatementStatement 物件物件 dbCon = DriverManager.getConnection(sCon);dbCon = DriverManager.getConnection(sCon); stmt = dbCon.createStatement();stmt = dbCon.createStatement(); // // 建立建立 SQLSQL 指令指令 String sSQL = "SELECT * FROM students";String sSQL = "SELECT * FROM students"; boolean state = stmt.execute(sSQL);boolean state = stmt.execute(sSQL); if ( state ) {if ( state ) { rs = stmt.getResultSet();rs = stmt.getResultSet(); // // 取得取得 ResultSetMetaDataResultSetMetaData 物件物件 md = rs.getMetaData();md = rs.getMetaData(); int count = md.getColumnCount();int count = md.getColumnCount(); String label, type;String label, type; int size;int size; out.print("out.print(" 資料表欄位數資料表欄位數 : " + count + "<br>");: " + count + "<br>"); for ( int i = 1; i <=count; i++ ) {for ( int i = 1; i <=count; i++ ) { label = md.getColumnLabel(i);label = md.getColumnLabel(i); size = md.getColumnDisplaySize(i);size = md.getColumnDisplaySize(i); type = md.getColumnTypeName(i);type = md.getColumnTypeName(i); out.print(i + ": out.print(i + ": 名稱名稱 : " + label);: " + label); out.print(" out.print(" 尺寸尺寸 : " + size);: " + size); out.print(" out.print(" 類型類型 : " + type + "<br>"); : " + type + "<br>"); }} }} stmt.close(); // stmt.close(); // 關閉關閉 StatementStatement 物件物件 dbCon.close(); // dbCon.close(); // 關閉連結關閉連結 }} catch(SQLException e) {catch(SQLException e) { out.print(e); out.print(e); }} %>%> </body></body> </html></html>

Page 23: 11-1 JDBC 的基礎 - 說明

11-4-2 11-4-2 顯示資料表的記錄資料顯示資料表的記錄資料 -- 步步驟四驟四

在這一節筆者準備執行在這一節筆者準備執行 SQLSQL 查詢指令取得資料表查詢指令取得資料表的記錄資料,步驟是繼續第的記錄資料,步驟是繼續第 11-2-211-2-2 節的步驟三。節的步驟三。

步驟四:使用步驟四:使用 StatementStatement 物件執行物件執行 SQLSQL 指令指令 在在 JSPJSP 程式執行程式執行 SQLSQL 查詢指令可以取得查詢結果查詢指令可以取得查詢結果的的 ResultSetResultSet 物件,這是使用物件,這是使用 executeQuery()executeQuery()方法取得方法取得 ResultSetResultSet 物件,如下所示:物件,如下所示:

rs = stmt.executeQuery(sSQL);rs = stmt.executeQuery(sSQL); 程式碼取得參數程式碼取得參數 SQLSQL 指令指令 sSQLsSQL 查詢結果的查詢結果的

ResultSetResultSet 物件物件 rsrs ,參數的,參數的 SQLSQL 查詢指令可以查詢指令可以取得資料表取得資料表 studentsstudents 的所有記錄。的所有記錄。

Page 24: 11-1 JDBC 的基礎 - 說明

11-4-2 11-4-2 顯示資料表的記錄資料顯示資料表的記錄資料 -- 步步驟五驟五

步驟五:使用迴圈取得步驟五:使用迴圈取得 ResultSetResultSet 物件的記錄物件的記錄 在取得查詢結果的在取得查詢結果的 ResultSetResultSet 物件後,可以使用物件後,可以使用

whilewhile 迴圈配合迴圈配合 next()next() 方法來顯示記錄,如下所方法來顯示記錄,如下所示:示:

while ( rs.next() ) {while ( rs.next() ) { out.print(rs.getString("stdno"));out.print(rs.getString("stdno")); out.print(rs.getString("name"));out.print(rs.getString("name")); out.print(rs.getString("address"));out.print(rs.getString("address")); out.print(rs.getDate("birthday"));out.print(rs.getDate("birthday")); out.print(rs.getInt("totalcredit"));out.print(rs.getInt("totalcredit"));}}

Page 25: 11-1 JDBC 的基礎 - 說明

11-4-2 11-4-2 顯示資料表的記錄資料顯示資料表的記錄資料 -- 步步驟五驟五

步驟六:關閉連結的步驟六:關閉連結的 ConnectionConnection和和StatementStatement 物件物件

在處理完資料庫的查詢或操作後,在處理完資料庫的查詢或操作後, JSPJSP 程程式需要關閉式需要關閉 ConnectionConnection和和 StatementStatement 物物件,使用的都是件,使用的都是 close()close() 方法,如下所示:方法,如下所示:

stmt.close();stmt.close();

dbCon.close();dbCon.close();

Page 26: 11-1 JDBC 的基礎 - 說明

範例範例 <!-- JSP<!-- JSP 程式:程式: Ch11_4_2.jsp -->Ch11_4_2.jsp --> <%@ page contentType="text/html; charset=MS950"<%@ page contentType="text/html; charset=MS950" import="java.sql.*"%>import="java.sql.*"%> <html><html> <head><title>Ch11_4_2.jsp</title></head><head><title>Ch11_4_2.jsp</title></head> <body><body> <h2><h2> 顯示資料表的記錄資料顯示資料表的記錄資料 </h2><hr></h2><hr> <table border="1"><table border="1"> <%<% Connection dbCon = null; // Connection dbCon = null; // 宣告物件變數宣告物件變數 Statement stmt = null;Statement stmt = null; ResultSet rs = null;ResultSet rs = null; // // 驅動程式參數驅動程式參數 String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; String sCon = "jdbc:odbc:school_db";String sCon = "jdbc:odbc:school_db"; try {try { // // 載入 載入 JDBC driver JDBC driver Class.forName(sDriver);Class.forName(sDriver); // // 建立資料連結和建立資料連結和 StatementStatement 物件物件 dbCon = DriverManager.getConnection(sCon);dbCon = DriverManager.getConnection(sCon); stmt = dbCon.createStatement();stmt = dbCon.createStatement(); // // 建立建立 SQLSQL 指令指令 String sSQL = "SELECT * FROM students";String sSQL = "SELECT * FROM students"; rs = stmt.executeQuery(sSQL);rs = stmt.executeQuery(sSQL); while ( rs.next() ) { // while ( rs.next() ) { // 使用迴圈顯示記錄資料 使用迴圈顯示記錄資料 out.print("<tr>");out.print("<tr>"); out.print("<td>"+rs.getString("stdno")+"</td>");out.print("<td>"+rs.getString("stdno")+"</td>"); out.print("<td>"+rs.getString("name")+"</td>");out.print("<td>"+rs.getString("name")+"</td>"); out.print("<td>"+rs.getString("address")+"</td>");out.print("<td>"+rs.getString("address")+"</td>"); out.print("<td>"+rs.getDate("birthday")+"</td>");out.print("<td>"+rs.getDate("birthday")+"</td>"); out.print("<td>"+rs.getInt("totalcredit")+"</td>"); out.print("<td>"+rs.getInt("totalcredit")+"</td>"); out.print("</tr>");out.print("</tr>"); }} stmt.close(); // stmt.close(); // 關閉關閉 StatementStatement 物件物件 dbCon.close(); // dbCon.close(); // 關閉連結關閉連結 }} catch(SQLException e) {catch(SQLException e) { out.print(e); out.print(e); }} %>%> </table></table> </body></body> </html></html>

Page 27: 11-1 JDBC 的基礎 - 說明

11-4-3 11-4-3 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫的中文問題料庫的中文問題 -- 編碼編碼

指定指定 JDBCJDBC 驅動程式的編碼驅動程式的編碼 在載入在載入 JDBCJDBC 驅動程式時,驅動程式時, JSPJSP 程式需要指定編程式需要指定編

碼參數來連結碼參數來連結 MySQLMySQL 資料庫,如下所示:資料庫,如下所示:String sCon = String sCon = "jdbc:mysql://localhost:3306/school?user=root&" + "jdbc:mysql://localhost:3306/school?user=root&" + "password=123456&useUnicode=true&characterEn"password=123456&useUnicode=true&characterEn

coding=MS950coding=MS950";";dbCon = DriverManager.getConnection(sCon);dbCon = DriverManager.getConnection(sCon); 上述上述 JDBCJDBC 驅動程式設定驅動程式設定 useUnicodeuseUnicode和和

characterEncodingcharacterEncoding 屬性值為屬性值為 truetrue和和 MS950MS950 ,,使用使用 UnicodeUnicode的的 MS950MS950 編碼。編碼。

Page 28: 11-1 JDBC 的基礎 - 說明

11-4-3 11-4-3 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫的中文問題料庫的中文問題 -Unicode-Unicode 字串字串 11

將中文欄位值轉換成將中文欄位值轉換成 UnicodeUnicode 字串字串 在在 JSPJSP 程式顯示透過程式顯示透過 JDBCJDBC 取得取得 MySQLMySQL 資資

料庫的中文記錄資料時,因為料庫的中文記錄資料時,因為 JDBCJDBC 驅動程驅動程式在轉換中文內碼時,一個中文字會被切式在轉換中文內碼時,一個中文字會被切割成割成 22 個字元,例如:個字元,例如: 0x41750x4175 會切割成會切割成0x410x41和和 0x750x75 。。

所以,所以, JSPJSP 程式在顯示中文的記錄資料時,程式在顯示中文的記錄資料時,需要先將欄位字串還原成完整中文內碼的需要先將欄位字串還原成完整中文內碼的UnicodeUnicode 字串,這就是字串,這就是 toUnicode()toUnicode() 方法方法的功能。的功能。

Page 29: 11-1 JDBC 的基礎 - 說明

11-4-3 11-4-3 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫的中文問題料庫的中文問題 -Unicode-Unicode 字串字串 22

String toUnicode(String s) { String toUnicode(String s) { if (s == null || s.length() == 0) { if (s == null || s.length() == 0) { return null;return null; } } byte[] buffer = new byte[s.length()];byte[] buffer = new byte[s.length()]; int i, j;int i, j; for (i = 0, j = 0; i < s.length(); i++) { for (i = 0, j = 0; i < s.length(); i++) { if ( s.charAt(i) >= 0x100 ) { if ( s.charAt(i) >= 0x100 ) { char c = (char) s.charAt(i); char c = (char) s.charAt(i); byte[] buf = (""+c).getBytes(); byte[] buf = (""+c).getBytes(); buffer[j++] = (byte) buf[0]; buffer[j++] = (byte) buf[0]; buffer[j++] = (byte) buf[1]; buffer[j++] = (byte) buf[1]; } } else else buffer[j++] = (byte) s.charAt(i); buffer[j++] = (byte) s.charAt(i); } } return new String(buffer,0,j); return new String(buffer,0,j); } }

Page 30: 11-1 JDBC 的基礎 - 說明

11-4-3 11-4-3 使用使用 JDBCJDBC 連結連結 MySQLMySQL 資資料庫的中文問題料庫的中文問題 -- 表單資料編碼表單資料編碼

指定表單傳送資料的編碼指定表單傳送資料的編碼 當當 SQLSQL 指令或欄位值使用表單方式傳遞中文內容指令或欄位值使用表單方式傳遞中文內容給給 JSPJSP 程式時,在程式時,在 JSPJSP 程式需要指定傳送的編碼程式需要指定傳送的編碼方式,如下所示:方式,如下所示:

request.setCharacterEncoding("MS950");request.setCharacterEncoding("MS950"); 上述程式碼使用上述程式碼使用 requestrequest 物件的物件的

setCharacterEncoding()setCharacterEncoding() 方法指定傳送的編碼方法指定傳送的編碼方式為方式為 MS950MS950 ,這和,這和 JDBCJDBC 驅動程式的編碼相驅動程式的編碼相同,如此同,如此 JSPJSP 程式才能送出正確的程式才能送出正確的 SQLSQL 指令,將指令,將中文欄位內容存入資料庫。中文欄位內容存入資料庫。

Page 31: 11-1 JDBC 的基礎 - 說明

11-5 SQL11-5 SQL語言的資料庫查詢語言的資料庫查詢 11-5-1 11-5-1 分頁顯示分頁顯示 SQLSQL 查詢結果查詢結果

Page 32: 11-1 JDBC 的基礎 - 說明

11-5-1 11-5-1 分頁顯示分頁顯示 SQLSQL 查詢結查詢結果果 -- 建立建立 StatementStatement 物件物件

建立分頁顯示的建立分頁顯示的 StatementStatement 物件物件 因為因為 ResultSetResultSet 物件的記錄資料需要使用物件的記錄資料需要使用

相關方法來移動記錄指標,如此才能分頁相關方法來移動記錄指標,如此才能分頁顯示查詢結果,所以在使用顯示查詢結果,所以在使用 ConnectionConnection物件的方法建立物件的方法建立 StatementStatement 物件時,需要物件時,需要設定指標型態和同步等級,如下所示:設定指標型態和同步等級,如下所示:

stmt = dbCon.createStatement(stmt = dbCon.createStatement(

ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_READ_ONLY);ResultSet.CONCUR_READ_ONLY);

Page 33: 11-1 JDBC 的基礎 - 說明

11-5-1 11-5-1 分頁顯示分頁顯示 SQLSQL 查詢結果查詢結果 --移移動記錄指標的方法動記錄指標的方法

ResultSetResultSet 物件移動記錄指標的相關方法物件移動記錄指標的相關方法方法 說明

boolean first() 移動記錄指標到第 1筆記錄,成功傳回 true

boolean last() 移動記錄指標到最後 1筆記錄,成功傳回 true

boolean isFirst() 檢查記錄指標是否是第 1筆記錄,是傳回 true

boolean isLast() 檢查記錄指標是否是最後 1筆記錄,是傳回 true

booleanisBeforeFirst()

檢查記錄指標是否在第 1筆記錄之前,是傳回 true

boolean isAfterLast() 檢查記錄指標是否在最後 1筆記錄之後,是傳回 true

int getRow() 取得目前這筆記錄是 ResultSet物件的第幾筆記錄,即記錄編號

boolean absolute(int) 移動記錄指標到參數記錄編號的第幾筆記錄,成功傳回 true

Page 34: 11-1 JDBC 的基礎 - 說明

11-5-1 11-5-1 分頁顯示分頁顯示 SQLSQL 查詢結果查詢結果 --分分頁顯示頁顯示 11

當當 JSPJSP 程式分頁顯示程式分頁顯示 SQLSQL 查詢結果時,首查詢結果時,首先需要計算出先需要計算出 ResultSetResultSet 物件的記錄總數,物件的記錄總數,如下所示:如下所示:

rs.last();rs.last();int totalRecords = rs.getRow();int totalRecords = rs.getRow(); 在取得記錄總數後,即可計算出這些記錄在取得記錄總數後,即可計算出這些記錄

一共可以分成幾頁來顯示,如下所示:一共可以分成幾頁來顯示,如下所示:totalPages = totalRecords/pageSize; totalPages = totalRecords/pageSize; if ( (totalRecords % pageSize) != 0 ) if ( (totalRecords % pageSize) != 0 )

totalPages++; totalPages++;

Page 35: 11-1 JDBC 的基礎 - 說明

11-5-1 11-5-1 分頁顯示分頁顯示 SQLSQL 查詢結果查詢結果 --分分頁顯示頁顯示 22

在計算出記錄數和分頁數後,只需使用在計算出記錄數和分頁數後,只需使用 URLURL 參數參數傳入顯示的分頁傳入顯示的分頁 pageNopageNo ,就可以移動記錄指標,就可以移動記錄指標到指定分頁的第到指定分頁的第 11 筆記錄,如下所示:筆記錄,如下所示:

rs.absolute((pageNo-1) * pageSize + 1); rs.absolute((pageNo-1) * pageSize + 1); 在在 JSPJSP 程式顯示分頁記錄是一個程式顯示分頁記錄是一個 do/whiledo/while 迴圈,迴圈,

因為我們已經使用因為我們已經使用 absloute()absloute() 方法移動記錄指標方法移動記錄指標到分頁的第到分頁的第 11 筆記錄,所以可以直接取得欄位值,筆記錄,所以可以直接取得欄位值,如下所示:如下所示:

int count = 0;int count = 0;do {do { count++;count++; ……… ………} while ( rs.next() && count < pageSize );} while ( rs.next() && count < pageSize );

Page 36: 11-1 JDBC 的基礎 - 說明

範例範例 <!-- JSP<!-- JSP 程式:程式: Ch11_5.jsp -->Ch11_5.jsp --> <%@ page contentType="text/html; charset=Big5"<%@ page contentType="text/html; charset=Big5" import="java.sql.*"%>import="java.sql.*"%> <html><html> <head><title>Ch11_5.jsp</title></head><head><title>Ch11_5.jsp</title></head> <%!<%! // // 驅動程式參數驅動程式參數 String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; String sCon = "jdbc:odbc:school_db";String sCon = "jdbc:odbc:school_db"; Connection dbCon = null;Connection dbCon = null; Statement stmt = null;Statement stmt = null; %>%> </head></head> <body><body> <center><h2><center><h2> 顯示資料庫的查詢結果顯示資料庫的查詢結果 </h2><hr></h2><hr> <%<% int pageNo = 1, pageSize = 3;int pageNo = 1, pageSize = 3; int totalPages = 1;int totalPages = 1; // // 取得表單欄位或取得表單欄位或 URLURL 參數資料參數資料 String sql = request.getParameter("Sql");String sql = request.getParameter("Sql"); // // 取得顯示的頁碼取得顯示的頁碼 if ( request.getParameter("Page") != null )if ( request.getParameter("Page") != null ) pageNo = Integer.parseInt(request.getParameter("Page")); pageNo = Integer.parseInt(request.getParameter("Page")); try { // try { // 載入 載入 JDBC driver JDBC driver Class.forName(sDriver);Class.forName(sDriver); // // 建立資料連結和建立資料連結和 StatementStatement 物件物件 dbCon = DriverManager.getConnection(sCon);dbCon = DriverManager.getConnection(sCon); stmt = dbCon.createStatement(stmt = dbCon.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);ResultSet.CONCUR_READ_ONLY); // // 執行執行 SQLSQL 指令指令 ResultSet rs = stmt.executeQuery(sql);ResultSet rs = stmt.executeQuery(sql); // // 計算記錄數計算記錄數

Page 37: 11-1 JDBC 的基礎 - 說明

rs.last(); // rs.last(); // 最後一筆記錄最後一筆記錄 int totalRecords = rs.getRow(); // int totalRecords = rs.getRow(); // 取得最後一筆的記錄數取得最後一筆的記錄數 , , 即總記錄數即總記錄數 if ( totalRecords > 0 ) { // if ( totalRecords > 0 ) { // 有記錄有記錄 totalPages = totalRecords/pageSize; // totalPages = totalRecords/pageSize; // 計算總頁數計算總頁數 if ( (totalRecords % pageSize) != 0 ) totalPages++; // if ( (totalRecords % pageSize) != 0 ) totalPages++; // 不能整除不能整除 , , 加一頁加一頁 rs.absolute((pageNo-1) * pageSize + 1); // rs.absolute((pageNo-1) * pageSize + 1); // 移動指標到該頁的第移動指標到該頁的第 11 筆記錄筆記錄 // // 表格標籤表格標籤 out.print("<p align='center'><table border=1>");out.print("<p align='center'><table border=1>"); ResultSetMetaData rsmd = rs.getMetaData();ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount();int columnCount = rsmd.getColumnCount(); // // 表格標題列表格標題列 out.print("<tr>");out.print("<tr>"); for (int i = 0; i < columnCount; i++ ) {for (int i = 0; i < columnCount; i++ ) { out.print("<th>");out.print("<th>"); out.print(rsmd.getColumnLabel(i+1)+"</th>");out.print(rsmd.getColumnLabel(i+1)+"</th>"); } } out.print("</tr>");out.print("</tr>"); // // 顯示記錄顯示記錄 int count = 0;int count = 0; do {do { count++;count++; out.print("<tr>");out.print("<tr>"); for (int i = 0; i < columnCount; i++ ) {for (int i = 0; i < columnCount; i++ ) { out.print("<td>");out.print("<td>"); out.print(rs.getString(i + 1) + "</td>");out.print(rs.getString(i + 1) + "</td>"); } } out.print("</tr>");out.print("</tr>"); } while ( rs.next() && count < pageSize );} while ( rs.next() && count < pageSize ); out.print("</table></p>");out.print("</table></p>"); out.print("<p>out.print("<p> 記錄數記錄數 : "+ totalRecords +"</p>");: "+ totalRecords +"</p>"); if ( pageNo > 1 ) // if ( pageNo > 1 ) // 有上一頁有上一頁 out.print("| <a href='Ch11_5.jsp?Page="+(pageNo-1)+out.print("| <a href='Ch11_5.jsp?Page="+(pageNo-1)+ "&Sql="+sql+"'>"&Sql="+sql+"'> 上一頁上一頁</a> |");</a> |"); if ( pageNo < totalPages ) // if ( pageNo < totalPages ) // 有下一頁有下一頁 out.print("| <a href='Ch11_5.jsp?Page="+(pageNo+1)+out.print("| <a href='Ch11_5.jsp?Page="+(pageNo+1)+ "&Sql="+sql+"'>"&Sql="+sql+"'> 下一頁下一頁</a> |");</a> |"); out.print(" (" + pageNo + "/" + totalPages + ")");out.print(" (" + pageNo + "/" + totalPages + ")"); }} else // else // 沒有記錄沒有記錄 out.print("<p>out.print("<p>沒有找到記錄沒有找到記錄 !</p>"); !</p>"); // // 關閉關閉 StatementStatement 物件物件 stmt.close();stmt.close(); // // 關閉連結關閉連結 dbCon.close();dbCon.close(); }} catch(SQLException e) {catch(SQLException e) { out.print(e); out.print(e); }} %></center>%></center> </body></body> </html></html>

Page 38: 11-1 JDBC 的基礎 - 說明

11-8-4 11-8-4 交易處理標籤交易處理標籤 -- 範例範例 JSTLJSTL的的 <sql:transaction><sql:transaction> 標籤可以將多個標籤可以將多個

<sql:query><sql:query>和和 <sql:update><sql:update> 標籤的標籤的 SQLSQL 查查詢與操作指令視為一個交易,如下所示:詢與操作指令視為一個交易,如下所示:

<sql:transaction><sql:transaction> <sql:query var="count"> <sql:query var="count"> SELECT * ……SELECT * …… </sql:query></sql:query> <sql:update var="count"> <sql:update var="count"> INSERT ………..INSERT ……….. </sql:update></sql:update></sql:transaction></sql:transaction>