Ch01 JDBC資料庫處理

Download Report

Transcript Ch01 JDBC資料庫處理

Ch18 JDBC資料庫處理
JAVA程式語言入門(II)
大綱
JDBC的基礎
 使用Access建立資料庫
 資料庫的基本存取

2015/7/20
2
JDBC的基礎-說明

「JDBC」(Java Database Connectivity)是
實作JDBC驅動程式介面(JDBC Driver
Interface)的類別,可以讓Java程式執行SQL
指令存取資料庫系統的記錄資料,例如:微軟
SQL Server、Access和Oracle等。
2015/7/20
3
JDBC的基礎-種類




JDBC-ODBC橋接驅動程式(JDBC-ODBC Bridge):Java程
式可以存取微軟ODBC資料來源的資料庫系統,本章就是以
JDBC驅動程式為例。
原生API的Java驅動程式(A Native-API Partly Java
Driver):將Java程式的JDBC呼叫轉換成專屬資料庫系統
的原生API呼叫。
Java網路協定驅動程式(A Net-protocol All Java
Driver):將Java程式的JDBC呼叫轉換成資料庫系統專屬
的網路協定,再由伺服器轉換成資料庫系統的API呼叫。
Java原生通訊協定驅動程式(A Native-protocol All
Java Driver):將Java程式的JDBC呼叫直接轉換成資料
庫系統原生通訊協定的API呼叫,以便客戶端可以直接連
線資料庫伺服器。
2015/7/20
4
JDBC的基礎-圖例

在本章的Java應用
程式是使用JDBC的
JDBC-ODBC橋接驅
動程式,透過
JDBC-ODBC驅動程
式存取ODBC資料來
源的關聯式資料庫
系統Access,如右
圖所示:
2015/7/20
5
使用Access建立資料庫-說明

Office家族的Access是一套桌上型資料庫系統
,適合個人和中小企業使用,筆者準備使用
Access建立本章Java應用程式使用JDBC連結的
資料庫。
2015/7/20
6
使用Access建立資料庫-欄位說
明

在Books.mdb資料庫擁有資料表Book,各欄位
的說明,如下表所示:
欄位名稱
BookID
BookTitle
BookAuthor
BookPrice
BookPubDate
2015/7/20
資料類型
文字
文字
文字
貨幣
日期/時間
長度
6
30
10
N/A
N/A
7
資料庫的基本存取
新增ODBC系統資料來源
 建立JDBC資料連結
 取得資料表的資訊
 顯示資料表記錄

2015/7/20
8
新增ODBC系統資料來源(1)


先建立一個ACCESS的資料庫
為上述的資料庫在ODBC中註冊一下:
1.
2.
3.
4.
5.

開始
控制台
效能及維護
系統管理工具
資料來源(ODBC)
在ODBC資料來源管理員下:
系統資料來源名稱
2. 新增
2015/7/20
1.
9
新增ODBC系統資料來源(2)

在Windows作業系統建立ODBC系統資料來源,新增
Access資料庫「Books.mdb」名為【book_list】
的ODBC系統資料來源,如下圖所示:
2015/7/20
10
建立JDBC資料連結的四步驟
1.
2.
3.
4.
載入驅動程式
建立Connection連結物件
建立JDBC的Statement物件
執行SQL指令來操作資料庫:查詢、新增、刪
除紀錄等的動作
2015/7/20
11
建立JDBC資料連結
步驟一-載入驅動程式
在Java應用程式首先需要載入驅動程式,因為是
透過ODBC存取資料庫,所以載入JDBC-ODBC驅
動程式,如下所示:
String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
Class.forName(sDriver);

上述程式碼的字串sDriver是驅動程式名稱,
接著載入JDBC-ODBC驅動程式。
2015/7/20
12
建立JDBC資料連結步驟二-建立Connection連結物件(1)

在載入JDBC-ODBC驅動程式後,就可以使用
DriverManager類別的getConnection()類別方
法建立Connection物件dbCon,如下所示:
Connection dbCon = null;
String sCon = "jdbc:odbc:book_list";
dbCon = DriverManager.getConnection(sCon);
*此處book_list要代換成前面所提到你為你的資料庫在ODBC
中所註冊的名字
2015/7/20
13
建立JDBC資料連結步驟二-建立Connection連結物件(2)

jdbc:通訊協定的URL字串,其格式如下所示:
jdbc:<subprotocol>:<subname>

subprotocol以此例是odbc,subname是系統資
料來源book_list。DriverManager類別的相關
方法,如下表所示:
方法
說明
Connection getConnection(String) 取得 Connection 物件,第 1 個參數是 URL
Connection getConnection(String, 字串,第 2 和 3 個參數 String 分別為使
String, String)
用者名稱和密碼
2015/7/20
14
建立JDBC資料連結步驟三-建立JDBC的Statement物件


Statement物件的目的是執行SQL指令,在建立
好Connection物件後,就可以使用
createStatement()方法建立Statement物件,
如下所示:
Statement stmt = dbCon.createStatement();
Connection類別的相關方法,如下表所示:
方法
Statement createStatement()
void close()
2015/7/20
說明
建立 Statement 物件
關閉 Connection 物件的資料庫連結資源
15
關閉連結的Connection和
Statement物件

在處理完資料庫的查詢或操作後,Java程式需
要關閉Connection和Statement物件,使用的
都是close()方法,如下所示:
try {
catch
try {
catch
2015/7/20
stmt.close(); }
( SQLException e ) {}
dbCon.close(); }
( SQLException e ) {}
16
範例1:測試資料庫的連結(1)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
import java.sql.*;
18. //步驟2:建立Connection連結物件
class Ch01_01
19.
Connection dbCon = null;
{
20.
Statement stmt = null;
public static void main(String [] args)
21.
String sCon = "jdbc:odbc:java4_Ch01";
{
22.
try
//步驟1:載入驅動程式
23.
{
String sDriver =
24.
dbCon =
"sun.jdbc.odbc.JdbcOdbcDriver";
DriverManager.getConnection(sCon);
try
25.
if(dbCon != null)
{
26.
System.out.println("建立資料來源連結
成功!");
Class.forName(sDriver);
27.
}
28.
//步驟3:建立JDBC的Statement物件
catch (Exception e)
29.
stmt = dbCon.createStatement();
{
if(stmt != null)
System.out.println("無法載入驅動程式");30.
31.
System.out.println("建立Statement物
return;
件成功!");
}
}
System.out.println("步驟1:驅動程式載入成功32.
!");
2015/7/20
17
範例1:測試資料庫的連結(2)
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
catch(SQLException e)
{
System.out.println("連結錯誤: " +
sCon);
System.out.println(e.getMessage());
if( dbCon != null)
{
try
{
dbCon.close();
}
catch(SQLException e2) {}
}
return;
}
finally
{
try
{
//關閉步驟3所開啟的statement物件
stmt.close();
}
catch(SQLException e) {}
try
{
//關閉步驟2所開啟的資料庫連結
dbCon.close();
}
catch(SQLException e) {}
}
}
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
2015/7/20
}
18
活動筋骨、腦部運動(1)
1.
2.
3.
建立一個ACCESS資料庫
在ODBC中註冊上一題中所建立的資料庫
改寫範例1程式,測試你的程式,確定你的
JAVA程式可以連結到資料庫
2015/7/20
19
執行SQL指令
執行SQL指令是繼續前面所提的步驟3,亦
即為步驟4。
 在建立資料庫連結和Statement物件後,就可
以進一步:

取得資料表資訊
 資料表的記錄資料

2015/7/20
20
取得資料表的資訊(1)

如何取得資料表資訊:資料表擁有多少欄位、
各欄位名稱和資料類型
步驟1:使用Statement物件執行SQL指令
 步驟2:取得ResultSet和ResultSetMetaData物件

2015/7/20
21
取得資料表的資訊(2)-步驟1

建立Statement物件的目的就是為了執行SQL指
令,如下所示:
boolean state = stmt.execute(sSQL);
 此處的sSQL是指SQL指令,一般會先宣告一個
String型態的字串變數sSQL,將SQL指令內容放在
此變數中
String sSQL = “SELECT * FROM Book”;
 上述程式碼的execute()方法執行參數的SQL指令字
串sSQL,這個SQL查詢指令字串可以取得資料表的
所有記錄。
2015/7/20
22
取得資料表的資訊(3)

Statement類別的相關方法,如下表所示:
方法
boolean execute(String)
ResultSet
executeQuery(String)
int executeUpdate(String)
ResultSet getResultSet()
void close()
2015/7/20
說明
執行參數的 SQL 指令字串,傳回值 true 表示
取得 ResultSet 物件,可以使用 getResultSet()
方法取得,如果沒有,傳回 false
執行參數的 SQL 查詢指令字串(SELECT 指
,傳回值是 ResultSet 物件
令)
執行參數的 SQL 操作指令字串(INSERT、
,傳回值是影響
DELETE 和 UPDATE 指令)
的記錄數
取得目前的 ResultSet 物件
關閉 Statement 物件
23
取得資料表的資訊(4)-步驟2
取得ResultSet和ResultSetMetaData物件

在使用Statement物件執行SQL指令後,接著使用
getResultSet()方法取得ResultSet物件,如下所
示:
ResultSet rs = stmt.getResultSet();

程式碼在取得ResultSet物件後,使用
getMetaData()方法取得ResultSetMetaData物件
,如下所示:
ResultSetMetaData md = rs.getMetaData();
2015/7/20
24
取得資料表的資訊(5)-步驟2
取得ResultSet和ResultSetMetaData物件

ResultSetMetaData類別的相關方法,如下表
所示:
方法
int getColumnCount()
int getColumnDisplaySize(int)
String getColumnLabel(int)
String
getColumnTypeName(int)
2015/7/20
說明
取得資料表共有多少欄位
取得資料表欄位的尺寸,參數是欄位編
號,從 1 開始
取得資料表欄位名稱,參數是欄位編號
取得資料表欄位的資料類型,參數是欄位
編號
25
範例2:取得資料表的資訊

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
將以下程式片斷插入到範例1的程式中第46與47行之間17.
//步驟4:取得資料表資訊
18.
ResultSet rs = null;
19.
ResultSetMetaData md = null;
20.
try
21.
{
22.
String sSQL = "SELECT * " +
23.
"FROM Book";
boolean state = stmt.execute(sSQL);
24.
if(state)
{
25.
rs = stmt.getResultSet();
26.
md = rs.getMetaData();
27.
int count = md.getColumnCount();
28.
String label, type;
29.
int size;
30.
System.out.println("資料表欄位數: " +31.
count);
2015/7/20
for(int i = 1; i <= count; i++)
{
label = md.getColumnLabel(i);
size = md.getColumnDisplaySize(i);
type = md.getColumnTypeName(i);
System.out.print(i + "==> 欄位名稱
: " + label);
System.out.print(" 欄位大小: " +
size);
System.out.println(" 資料型態: " +
type);
}
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
26
顯示資料表的記錄內容(1)

執行SQL查詢指令取得資料表的記錄資料,其
步驟:
1.
2.
使用Statement物件執行SQL指令
使用迴圈取得ResultSet物件的記錄
2015/7/20
27
顯示資料表的記錄內容(2)-步
驟1:執行SQL查詢指令
在Java程式執行SQL查詢指令可以取得查詢結果的
ResultSet物件,不同於前面,此處是直接使用
executeQuery()方法取得ResultSet物件,如下所
示:
ResultSet rs = stmt.executeQuery(sSQL);
 程式碼取得參數SQL指令sSQL查詢結果的
ResultSet物件,參數的SQL查詢指令可以取得資
料表Book的所有記錄。

2015/7/20
28
顯示資料表的記錄內容(3)-步驟2:
使用迴圈取得ResultSet物件的記錄
在取得查詢結果的ResultSet物件後,可以使用
while迴圈配合next()方法顯示記錄,如下所示:
while ( rs.next() )
{ int num; // 欄位編號
num = rs.findColumn("BookID");
System.out.print(num + ": ");
System.out.print(rs.getString("BookID"));
………
}
2015/7/20
29
範例3:取得資料表記錄內容

請將下列程式
碼插入到範例1
的程式碼中第
46與47行間
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
2015/7/20
//步驟4:顯示資料表的記錄內容
try
{
String sSQL = "SELECT * " +
"FROM Book";
ResultSet rs = stmt.executeQuery(sSQL);
while (rs.next())
{
int num;
num = rs.findColumn("BookID");
System.out.print(num + " : ");
System.out.print(rs.getString("BookID"));
num = rs.findColumn("BookTitle");
System.out.print(" " + num + " : ");
System.out.print(rs.getString("BookTitle"));
num = rs.findColumn("BookAuthor");
System.out.print(" " + num + " : ");
System.out.print(rs.getString("BookAuthor"));
num = rs.findColumn("BookPrice");
System.out.print(" " + num + " : ");
System.out.print(rs.getFloat("BookPrice"));
num = rs.findColumn("BookPubDate");
System.out.print(" " + num + " : ");
System.out.println(rs.getDate("BookPubDate"));
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
30
Ch02 SQL的簡單介紹
JAVA程式設計(4)
大綱
SQL語言的資料庫查詢
 SQL語言的資料庫操作

SQL語言的基礎-什麼是SQL語言


「SQL」(Structured Query Language)為「
ANSI」(American National Standards
Institute)標準的資料庫語言,SQL指令語法可
以用來查詢、新增、刪除和更新資料庫的記錄,
目前Access、SQL Server、DB2、MySQL、MySQL
MaxDB、Oracle和Sybase等資料庫管理系統都以
ANSI的SQL語言作為標準的資料庫語言。
早在1970年,E. F. Codd建立關聯性資料庫的觀
念,同時提出構想的資料庫語言,這是一種完整
和通用的資料存取方式,雖然在當時並沒有真正
建立語法,但這就是SQL的源起。
SQL語言的基礎-分類

SQL語言的指令可以分為三大部分,如下表
所示:
資料定義語言(Data Definition Language,
DLL):建立資料表、索引和視界(Views)等,
並且定義資料表的欄位。
 資料操作語言(Data Manipulation Language,
DML):屬於資料表記錄查詢、插入、刪除和更
新指令。
 資料控制語言(Data Control Language,DCL)
:屬於資料庫安全設定和權限管理的相關指令。

SQL語言的基礎-SELECT指令說明
SQL查詢指令 - SELECT
 Java程式在使用JDBC連結資料庫後,可以使用SQL
指令進行資料庫查詢,SQL的資料查詢指令只有一
個SELECT指令,完整指令語法如下所示:
SELECT 欄位1, 欄位2 FROM 資料表 WHERE
conditions
 上述SELECT指令的欄位1~2為記錄的欄位,
conditions是查詢條件,指令使用口語來說是「從
資料表取回符合WHERE子句條件的記錄,顯示欄位1
和2」。
SQL語言的基礎-指令1
“*”記錄欄位
 在上述SQL語法的欄位1~2是取回的資料表欄
位,我們可以使用”*”符號代表所有欄位
,表示取回資料表記錄的所有欄位,如下所
示:
SELECT * FROM Book

上述指令沒有WHERE子句,所以將資料表內
所有的記錄和欄位取回。
SQL語言的基礎-指令2
單一查詢條件的WHERE子句
 SQL查詢指令的單一條件,WHERE子句的基
本規則和範例,如下所示:
文字欄位要加上單引號,例如:書號P611,如
下所示:
SELECT * FROM Book WHERE BookID=’P611’
 數值欄位並不需要額外的字元括起,例如:書
價大於560元,如下所示:
SELECT * FROM Book WHERE BookPrice > 560

SQL語言的基礎-指令3
文字的欄位可以使用【LIKE】包含運算子配合
”%”萬用字元,此時查詢的條件子句只需包
含的子字串就符合條件,例如:書號內包含有
“7”的子字串,如下所示:
SELECT * FROM Book WHERE BookID LIKE
‘%7%’
 數值或日期欄位可以使用<>、>、<、>=和<=不
等於、大於、小於、大於等於和小於等於等運
算子建立多樣化的查詢條件。

SQL語言的基礎-指令4
多重查詢條件的WHERE子句
 WHERE子句的查詢條件可以使用AND和OR邏輯運算
子連接,其基本語法,如下所示:
AND且運算子:連接的前後條件都必須成立,整個條件
才成立,例如:書號包含“7”且書名有“網頁”的子
字串,如下所示:
SELECT * FROM Book WHERE BookID LIKE ‘%7%’ AND
BookTitle LIKE ‘%網頁%’
 OR或運算子:連接的前後條件只需任何一個成立即可
,例如:書號包含“5”或書名有“程式”的子字串,
如下所示:
SELECT * FROM Book WHERE BookID LIKE ‘%5%’ OR
BookTitle LIKE ‘%程式%’

SQL語言的基礎-指令5
排序輸出
 SQL的查詢結果可以指定欄位進行由小到大,或由
大到小排序,只需在SELECT指令的最後加上ORDER
BY子句即可,如下所示:
SELECT * FROM Book WHERE BookPrice>=500 ORDER
BY BookPrice
 上述查詢結果使用BookPrice欄位排序,預設是由
小到大的ASC,如果想倒過來由大到小,只需加上
DESC,如下所示:
SELECT * FROM Book WHERE BookPrice>=500 ORDER
BY BookPrice DESC
SQL指令查詢的程式範例

測試:建立命令列和GUI介面的2種資料庫查
詢程式,只需輸入SQL指令敘述,就可以看
到查詢結果。
範例1:執行程式時才輸入SQL
1.
2.
3.
4.
5.
6.
//步驟4:顯示資料表的記錄內容
try
{
//原來是在程式中設定SQL內容,但現在改成在執行此類別時才輸入SQL
//此處的SQL 可以是:"SELECT * FROM BOOK"
String sSQL = args[0];
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
ResultSet rs = stmt.executeQuery(sSQL);
while (rs.next())
{
int num;
num = rs.findColumn("BookID");
System.out.print(num + " : ");
System.out.print(rs.getString("BookID"));
num = rs.findColumn("BookTitle");
System.out.print(" " + num + " : ");
System.out.print(rs.getString("BookTitle"));
num = rs.findColumn("BookAuthor");
System.out.print(" " + num + " : ");
System.out.print(rs.getString("BookAuthor"));
num = rs.findColumn("BookPrice");
System.out.print(" " + num + " : ");
System.out.print(rs.getFloat("BookPrice"));
num = rs.findColumn("BookPubDate");
System.out.print(" " + num + " : ");
System.out.println(rs.getDate("BookPubDate"));
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
範例2:GUI介面的SQL查詢程
式

GUI介面查詢程式,只需在文字方塊欄位輸
入SQL指令,按【查詢】鈕,可以在下方的
文字區域顯示查詢到的每一筆記錄資料。
27.
28.
29.
//連結資料庫
//步驟1:載入驅動程式
String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
try
{
Class.forName(sDriver);
}
catch (Exception e)
{ System.out.println("無法載入驅動程式");
return;
}
System.out.println("步驟1:驅動程式載入成功!");
//步驟2:建立Connection連結物件
// Connection dbCon = null;
// Statement stmt = null;
String sCon = "jdbc:odbc:java4_Ch01";
try
{ dbCon = DriverManager.getConnection(sCon);
if(dbCon != null)
System.out.println("建立資料來源連結成功!");
//步驟3:建立JDBC的Statement物件
stmt = dbCon.createStatement();
if(stmt != null)
System.out.println("建立Statement物件成功!");
}
catch(SQLException e)
{ System.out.println("連結錯誤: " + sCon);
System.out.println(e.getMessage());
if( dbCon != null)
{ try
{
dbCon.close();
}
catch(SQLException e2) {}
}
return;
}
範例2:程式碼(1)
30.
31.
32.
33.
34.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.sql.*;
class Ch02_02 extends JFrame
{
private Container c;
private JLabel label;
private JTextField text;
private JButton button;
private JTextArea area;
static Connection dbCon = null;
static Statement stmt = null;
public Ch02_02()
{
super("SQL查詢程式");
c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.CENTER));
label = new JLabel("SQL指令: ");
text = new JTextField("
", 25);
button = new JButton("查詢");
area = new JTextArea("等待輸入SQL中...\n", 18,
40);
c.add(label);
c.add(text);
c.add(button);
c.add(new JScrollPane(area));
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
範例2:程式碼(2)
num = rs.findColumn("BookAuthor");
output += " " + num + " : ";
output += rs.getString("BookAuthor");
num = rs.findColumn("BookPrice");
output += " " + num + " : ";
output += rs.getFloat("BookPrice");
num = rs.findColumn("BookPubDate");
output += " " + num + " : ";
output += rs.getDate("BookPubDate") +
84.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
//建立button的傾聽者,並可以執行button的動作
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent
evt)
{
String output = "";
//步驟4:顯示資料表的記錄內容
try
{ area.setText(""); //清除顯示查詢結
果的區域
//原來是在程式中設定SQL內容,但現在改成
在執行此類別時才輸入SQL
//此處的SQL 可以是:"SELECT * FROM
BOOK"
String sSQL = text.getText();
ResultSet rs =
stmt.executeQuery(sSQL);
while (rs.next())
{
int num;
num = rs.findColumn("BookID");
output += num + " : ";
output += rs.getString("BookID");
num = rs.findColumn("BookTitle");
output += " " + num + " : ";
output +=rs.getString("BookTitle");
85.
86.
87.
88.
89.
90.
91.
92.
"\n";
}
93.
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
if (output == "")
area.append("找不到符合條件的資料!\n");
else
area.append(output); //新增查詢結果
area.append("查詢完成....\n");
94.
95.
96.
97.
98.
99.
100.
101.
102.
}
});
103.
104.
105.
}
範例2:程式碼(3)
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
public static void main(String [] args)
{
Ch02_02 f = new Ch02_02();
f.addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent
we)
{
try
{
//關閉步驟3所開啟的statement物件
stmt.close();
}
catch(SQLException e) {}
try
{
//關閉步驟2所開啟的資料庫連結
dbCon.close();
}
catch(SQLException e) {}
System.exit(0);
}
});
f.setSize(450, 400);
f.setVisible(true);
}
練習1
是否會覺得範例2的程式碼好長, 這在開發系
統時,會造成程式不易閱讀
 試一試,將有關DB連結的部份另外形成一個類
別

SQL語言的資料庫查詢-類別
方法


課本中將有關與資料庫連結的部份成立一個類別
Ch15_4
類別提供3個類別方法,可以分別開啟資料庫連結
、執行SQL查詢和關閉資料庫連結,如下表所示:
方法
Ch15_4.openODBC(Str1,Str2,Str3)
Ch15_4.closeODBC()
String Ch15_4.queryTable(String)
說明
開啟 JDBC-ODBC 資料庫連結,參數
依序為系統資料來源 DSN 字串、使用
者名稱和密碼
關閉資料庫連結
執行參數的 SQL 查詢字串,在取得資
料表資訊後,依序取得每筆記錄的欄
位名稱和欄位值,傳回查詢結果的字
串
SQL語言的資料庫查詢-類別
變數

在Ch15_4類別提供2個類別變數參考
Connection和Statement物件,如下表所示:
類別變數
Ch15_4. dbCon
Ch15_4.stmt
說明
開啟 JDBC-ODBC 資料連結建立的 Connection 物件
使用 createStatement()方法建立的 Statement 物件
範例3:將資料庫連結部份另外建立一個
類別(1)_Ch02_03_DB.java
22.
1.
import java.sql.*;
2.
public class Ch02_03_DB
{
static Connection dbCon = null;
static Statement stmt = null;
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
//載入驅動程式JdbcOdbc方法
static void load_Driver()
{
String sDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
try
{
Class.forName(sDriver);
}
catch (Exception e)
{
System.out.println("無法載入驅動程式");
return;
}
System.out.println("步驟1:驅動程式載入成功!");
return;
}
23.
24.
25.
26.
27.
28.
29.
//建立Connection連結物件及Statement物件的方法
static void connect_DBObject(String sCon)
{
try
{
dbCon = DriverManager.getConnection(sCon);
if(dbCon != null)
System.out.println("建立資料來源連結成功!");
30.
31.
32.
33.
34.
!");
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
//建立JDBC的Statement物件
stmt = dbCon.createStatement();
if(stmt != null)
System.out.println("建立Statement物件成功
}
catch(SQLException e)
{
System.out.println("連結錯誤: " + sCon);
System.out.println(e.getMessage());
if( dbCon != null)
{
try
{
dbCon.close();
}
catch(SQLException e2) {}
}
return;
}
return;
範例3:將資料庫連結部份另外建立一個
類別(2)_Ch02_03_DB.java
70.
71.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
//關閉資料庫連結
static void close_DB()
{
try
{
//關閉步驟3所開啟的statement物件
stmt.close();
}
catch(SQLException e) {}
try
{
//關閉步驟2所開啟的資料庫連結
dbCon.close();
}
catch(SQLException e) {}
67.
return;
68.
69.
}
72.
73.
74.
75.
76.
77.
//執行SQL語言,並將結果以String傳回
static String execute_SQL(String sSQL)
{
String output = "";
try
{
//原來是在程式中設定SQL內容,但現在改成在執行此類別時才輸入SQL
//此處的SQL 可以是:"SELECT * FROM BOOK"
78.
ResultSet rs = stmt.executeQuery(sSQL);
while (rs.next())
{
int num;
num = rs.findColumn("BookID");
output += num + " : ";
output += rs.getString("BookID");
num = rs.findColumn("BookTitle");
output += " " + num + " : ";
output += rs.getString("BookTitle");
num = rs.findColumn("BookAuthor");
output += " " + num + " : ";
output += rs.getString("BookAuthor");
num = rs.findColumn("BookPrice");
output += " " + num + " : ";
output += rs.getFloat("BookPrice");
num = rs.findColumn("BookPubDate");
output += " " + num + " : ";
output += rs.getDate("BookPubDate") + "\n";
}
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
return output;
99.
100.
101.
102.
103.
104.
}
105.
106.
}
範例3:將資料庫連結部份另外建立一個
類別(3)_Ch02_03.java
24.
25.
1.
2.
3.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
26.
//連結資料庫
//步驟1:載入驅動程式
Ch02_03_DB.load_Driver();
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch02_03_DB.connect_DBObject(sCon);
27.
28.
4.
5.
6.
7.
8.
9.
10.
class Ch02_03 extends JFrame
{
private Container c;
private JLabel label;
private JTextField text;
private JButton button;
private JTextArea area;
29.
//建立button的傾聽者,並可以執行button的動作
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
//步驟4:顯示資料表的記錄內容
area.setText(""); //清除顯示查詢結果的區域
30.
31.
32.
33.
34.
35.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public Ch02_03()
{
super("SQL查詢程式");
c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.CENTER));
label = new JLabel("SQL指令: ");
text = new JTextField("
", 25);
button = new JButton("查詢");
area = new JTextArea("等待輸入SQL中...\n", 18, 40);
c.add(label);
c.add(text);
c.add(button);
c.add(new JScrollPane(area));
36.
37.
輸入SQL
//此處的SQL 可以是:"SELECT * FROM BOOK"
//呼叫Ch02_03_DB執行SQL的方法
38.
39.
String sSQL = text.getText();
String output = Ch02_03_DB.execute_SQL(sSQL);
40.
41.
if (output == "")
area.append("找不到符合條件的資料!\n");
else
area.append(output); //新增查詢結果
area.append("查詢完成....\n");
42.
43.
44.
45.
46.
}
});
47.
48.
49.
50.
//原來是在程式中設定SQL內容,但現在改成在執行此類別時才
}
範例3:將資料庫連結部份另外建立一個
類別(4)_Ch02_03.java
63.
public static void main(String []
args)
{
Ch02_03 f = new Ch02_03();
f.addWindowListener(new
WindowAdapter()
{ public void
windowClosing(WindowEvent we)
{
Ch02_03_DB.close_DB();
System.exit(0);
}
});
f.setSize(450, 400);
f.setVisible(true);
}
64.
}
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.

範例3中,雖可以看到所有資料內容,但是如果
我們想看到每一次畫面中只有出現一筆資料,
程式如何撰寫?
範例4:每一次顯示一筆資料
範例4:程式(1/3)
1.
2.
3.
4.
5.
6.
7.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.sql.*;
class Ch02_04 extends JFrame implements ActionListener
{
private Container c;
25.
26.
27.
28.
29.
30.
31.
8.
9.
private JPanel showData = new JPanel(new
GridLayout(5,2,2,2));
private JPanel buttonSet = new JPanel(new GridLayout(1,4));
private
private
private
private
private
JLabel
JLabel
JLabel
JLabel
JLabel
private
private
private
private
private
JTextField
JTextField
JTextField
JTextField
JTextField
23.
private
private
private
private
JButton
JButton
JButton
JButton
24.
private ResultSet rs = null;
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
bid_label = new JLabel("書
號 :");
btitle_label = new JLabel("書
名 :");
bauthor_label = new JLabel("作
者 :");
bprice_label = new JLabel("價
格 :");
bpubdate_label = new JLabel("出版日期 :");
bid_text = new JTextField(30);
btitle_text = new JTextField(30);
bauthor_text = new JTextField(30);
bprice_text = new JTextField(30);
bpubdate_text = new JTextField(30);
first_button = new JButton("第一筆");
pre_button = new JButton("前一筆");
next_button = new JButton("下一筆");
final_button = new JButton("最後一筆");
public Ch02_04()
{
super("SQL查詢程式");
c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.CENTER));
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
//將要顯示紀錄內容的欄位標籤及內容的元件加入到showData JPanel上
showData.add(bid_label);
showData.add(bid_text);
showData.add(btitle_label);
showData.add(btitle_text);
showData.add(bauthor_label);
showData.add(bauthor_text);
showData.add(bprice_label);
showData.add(bprice_text);
showData.add(bpubdate_label);
showData.add(bpubdate_text);
//將前一筆,下一筆的按鈕裝到buttonSet JPanel上
buttonSet.add(first_button);
buttonSet.add(pre_button);
buttonSet.add(next_button);
buttonSet.add(final_button);
//將兩個JPanel裝到container上
c.add(showData);
c.add(buttonSet);
範例4:程式(2/3)
50.
51.
52.
//連結資料庫
//步驟1:載入驅動程式
Ch02_03_DB.load_Driver();
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
}
66.
67.
68.
69.
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch02_03_DB.connect_DBObject(sCon);
70.
//步驟3:執行SQL指令:"SELECT * FROM BOOK"
String sSQL = "SELECT * "
+ "FROM BOOK";
rs = Ch02_03_DB.execute_SQL_RS(sSQL);
74.
//為每一個按鈕裝上傾聽者
first_button.addActionListener(this);
pre_button.addActionListener(this);
next_button.addActionListener(this);
final_button.addActionListener(this);
79.
71.
72.
73.
75.
76.
77.
78.
//實作按鈕的工作內容
public void actionPerformed(ActionEvent e)
{
String 按鈕標記 = e.getActionCommand();
try
{
if(按鈕標記.equals("第一筆"))
rs.first();
if(按鈕標記.equals("前一筆"))
rs.previous();
if(按鈕標記.equals("下一筆"))
rs.next();
if(按鈕標記.equals("最後一筆"))
rs.last();
80.
81.
82.
//將記錄內容依各欄位分別放到各個相對的
textfiled內
bid_text.setText(rs.getString("BookID"));
83.
btitle_text.setText(rs.getString("BookTitle"));
84.
bauthor_text.setText(rs.getString("BookAuthor"));
85.
86.
87.
88.
89.
90.
bprice_text.setText(Float.toString(rs.getFloat("Book
Price")));
String out = "" + rs.getDate("BookPubDate");
bpubdate_text.setText(out);
}
catch(SQLException r)
{ r.printStackTrace(); }
範例4:程式(3/3)
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
public static void main(String []
args)
{
Ch02_04 f = new Ch02_04();
f.addWindowListener(new
WindowAdapter()
{ public void
windowClosing(WindowEvent we)
{
Ch02_03_DB.close_DB();
System.exit(0);
}
});
f.setSize(680, 200);
f.setVisible(true);
}

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
105.
106.
}
CH02_03_DB.java中有關execute_SQL_RS方法的
程式碼
//執行SQL語言,並將結果以ResultSet傳回
static ResultSet execute_SQL_RS(String
sSQL)
{
ResultSet rs = null;
try
{
//原來是在程式中設定SQL內容,但現在
改成在執行此類別時才輸入SQL
//此處的SQL 可以是:"SELECT * FROM
BOOK"
13.
rs = stmt.executeQuery(sSQL);
}
catch(SQLException e)
{
14.
15.
16.
System.out.println(e.getMessage());
}
return rs;

執行範例4時,達到一次可以看到一筆資料,可
是,資料只可以每一次看下一筆記錄,卻無法直
接看到第一筆、前一筆、最後一筆, 如何解決
???
可捲動式ResultSets

要讓游標可以前後移動,在
connection.createStatement()時就要指定
public Statement createStatement() throws
SQLException
 Public Statement createStatement(int sType,
int sConcurrency) throws SQLException

 sType:



指定ResultSet可否捲動,其常數有
TYPE_FORWARD_ONLY:不可捲動,只可向前
TYPE_SCROLL_INSENITIVE: 可捲動,無法立刻看到更新結果
TYPE_SCROLL_SENSITIVE:可捲動,並可立刻看到更新結果
 sConcurrency:


指定ResultSet是唯讀或可更新
CONCUR_READ_ONLY
CONCUR_UPDATABLE
將游標移至指定的資料列








first():第一筆
last():最後一筆
beforeFirst():在第一筆之前
afterLast():在最後一筆之後
next():下一筆
previous():前一筆
absolute(int rowNumber):在第rowNumber筆
relative(int rowNmuber):以目前游標所在向後(
前:rowNmuber為負)移動rowNumber筆
取得游標位置
isFirst()
 isLast()
 isBeforeFirst()
 isAfterLast():結果集合為空集合時,會傳
回false
 getRow()

範例5:可移動資料項目

修改Ch02_03_DB.java中的connect_DBObject方法
1.
static void connect_DBObject(String sCon)
{
try
{
dbCon = DriverManager.getConnection(sCon);
if(dbCon != null)
System.out.println("建立資料來源連結成功
!");
2.
3.
4.
5.
6.
7.
8.
14.
15.
16.
17.
18.
19.
20.
21.
//建立JDBC的Statement物件
9.
stmt = dbCon.createStatement(
10.
22.
23.
24.
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
11.
12.
13.
功!");
}
if(stmt != null)
System.out.println("建立Statement物件成
catch(SQLException e)
{
System.out.println("連結錯誤:
" + sCon);
25.
26.
27.
28.
29.
System.out.println(e.getMessage());
if( dbCon != null)
{
try
{
dbCon.close();
}
catch(SQLException e2) {}
}
return;
}
return;
}
練習2
是不是覺得範例4的程式好像也很長,可不可以
將有關畫面的設計也切割出來,另外成為一個
類別???
 如果可以,那麼我們以後就更可以作視窗的程
式設計師,專門處理視窗,作DB的程式設計師,
專門處理DB了!

SQL語言的資料庫操作
插入記錄
 更新記錄
 刪除記錄

SQL語言的資料庫操作
Java程式一樣可以使用JDBC執行SQL資料表操
作指令來維護或更新資料表的記錄資料,這
就是資料表插入、刪除和更新記錄的SQL指令
:INSERT、DELETE和UPDATE。
 在這一節的程式範例也是使用Ch15_4類別的
方法和變數,以便減少Java程式碼的長度。

插入記錄-說明
SQL語言插入記錄指令INSERT可以新增一筆
記錄到資料表,INSERT指令的語法格式,如
下所示:
INSERT INTO table
(column1,column2,…..) VALUES
('value1', 'value2 ', …)
 table為準備插入記錄的資料表名稱,
column1~n為資料表的欄位名稱清單,只需
列出使用到的欄位,value1~n是對應的欄位
值。

插入記錄-注意事項
不論欄位或值的清單,都需要使用逗號分隔
。
 INSERT指令VALUES的值,數值不用單引號包
圍,字元需要單引號包圍,日期時間需要
”#”符號。
 INSERT指令的欄位名稱清單,並不需要和資
料表定義的欄位數目或順序相同,只需選擇
需要新增資料的欄位,但是括號內的欄位名
稱順序需和VALUES值的順序相同。

插入記錄-範例
例如:在資料表Book插入一筆圖書記錄的SQL指
令,如下所示:
INSERT INTO Book
(BookID,BookTitle,BookAuthor,
BookPrice,BookPubDate)
VALUES ('L333','PHP網頁設計範例教本','陳會安
',
560.0,#06/06/2003#)
 在Java程式只需使用Statement物件的
executeUpdate()方法執行SQL指令就可以插入一
筆圖書記錄,如下所示:
Ch15_4.stmt.executeUpdate(strSQL);

更新記錄-說明
SQL語言更新記錄指令UPDATE是將資料表內符合條
件的記錄,都更新成指定的欄位值,UPDAT E指令
的語法格式,如下所示:
UPDATE table SET column1 = ‘value1’ WHERE
conditions
 table是資料表,SET子句column1是資料表的欄位
名稱,這是需要更新的欄位,value1是更新的欄
位值,如果更新欄位不只一個,請使用逗號分隔
,其語法格式,如下所示:
UPDATE table SET column1 = 'value1' , column2
= 'value2' WHERE conditions

更新記錄-注意事項
WHERE子句是必要元素,如果沒有WHERE子句
,資料表內所有記錄欄位都會被更新。
 更新欄位值是數值不用單引號包圍,字元需
要使用單引號包圍,日期時間為”#”符號。

更新記錄-範例

例如:在資料表Book更改記錄圖書資料的SQL
指令,如下所示:
UPDATE Book SET BookPrice=580.0,
BookPubDate=#8/8/2003#
WHERE BookID='L333'

上述SQL指令的WHERE條件為圖書書號BookID欄
位,使用SET子句更新欄位資料。
刪除記錄-說明

SQL語言刪除記錄指令DELETE是將資料表內符
合條件的記錄通通刪除掉。DELETE指令的語
法格式,如下所示:
DELETE FROM table WHERE conditions

table是資料表,WHERE子句conditions為刪
除記錄的條件,口語來說是「將符合
conditions條件的記錄刪除掉」。
刪除記錄-注意事項與範例

DELETE指令的注意事項,如下所示:


WHERE子句是DELETE指令的必要元素,如果沒有
WHERE子句,資料表內的所有記錄都會被刪除。
例如:在資料表Book刪除一筆圖書記錄的SQL
指令,如下所示:
DELETE FROM Book WHERE BookID='L333'
範例1:將Book資料庫顯示在視窗中
1.
2.
3.
4.
5.
6.
7.
8.
import
import
import
import
java.awt.*;
java.util.*;
javax.swing.*;
java.sql.*;
public class Ex03_01 extends JFrame
{
static final String JDBC_DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";
static final String DATABASE_URL = "jdbc:odbc:book";
9.
11.
private Connection con;
private Statement stmt;
12.
String query = "SELECT 編號, 書名, 作者, 書價 FROM bookITEM";
10.
13.
14.
15.
16.
17.
18.
19.
//launch the application
public static void main(String args[])
{
Ex03_01 window = new Ex03_01();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
//建構子, 包括設定資料庫的初始連線
public Ex03_01()
{ super("Books Database");
//connect to database book and query database
try
{ Class.forName(JDBC_DRIVER);
con = DriverManager.getConnection(DATABASE_URL);
stmt = con.createStatement();
ResultSet resultSet = stmt.executeQuery(query);
//process query results
StringBuffer results = new StringBuffer();
ResultSetMetaData metaData = resultSet.getMetaData();
int numberOfColumns = metaData.getColumnCount();
for (int i = 1; i <= numberOfColumns; i++)
results.append(metaData.getColumnName(i) + "\t");
results.append("\n");
while (resultSet.next())
{ for( int i = 1; i <= numberOfColumns; i++)
results.append(resultSet.getObject(i) + "\t");
results.append("\n");
}
//set up GUI and display window
JTextArea textArea = new JTextArea(results.toString());
Container container = getContentPane();
container.add(new JScrollPane(textArea));
setSize(300, 100); //window size
setVisible(true); //display window
} //end try
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
//detect problems interacting with the database
catch(SQLException sqlException)
{ JOptionPane.showMessageDialog(null, sqlException.getMessage(),
"Database error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
//detect problems loading database driver
catch(ClassNotFoundException classNotFound)
{ JOptionPane.showMessageDialog(null, classNotFound.getMessage(),
"Drive not Found", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
//ensure statement and connection are closed properly
finally
{ try
{ stmt.close();
con.close();
}
//handle exceptions closing statement and connection
catch(SQLException sqlException)
{ JOptionPane.showMessageDialog(null, sqlException.getMessage(),
"Database Error",
JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
}//end constructor
Ch03 SQL的資料庫操作介紹
JAVA程式設計(4)
SQL語言的資料庫操作
插入記錄
 更新記錄
 刪除記錄

SQL語言的資料庫操作

Java程式一樣可以使用JDBC執行SQL資料表操
作指令來維護或更新資料表的記錄資料,這
就是資料表插入、刪除和更新記錄的SQL指令
:INSERT、DELETE和UPDATE。
插入記錄-說明
SQL語言插入記錄指令INSERT可以新增一筆
記錄到資料表,INSERT指令的語法格式,如
下所示:
INSERT INTO table
(column1,column2,…..) VALUES
('value1', 'value2 ', …)
 table為準備插入記錄的資料表名稱,
column1~n為資料表的欄位名稱清單,只需
列出使用到的欄位,value1~n是對應的欄位
值。

插入記錄-注意事項
不論欄位或值的清單,都需要使用逗號分隔
。
 INSERT指令VALUES的值,數值不用單引號包
圍,字元需要單引號包圍,日期時間需要
”#”符號。
 INSERT指令的欄位名稱清單,並不需要和資
料表定義的欄位數目或順序相同,只需選擇
需要新增資料的欄位,但是括號內的欄位名
稱順序需和VALUES值的順序相同。

插入記錄-範例
例如:在資料表Book插入一筆圖書記錄的SQL指
令,如下所示:
INSERT INTO Book
(BookID,BookTitle,BookAuthor,
BookPrice,BookPubDate)
VALUES ('L333','PHP網頁設計範例教本','陳會安
',
560.0,#06/06/2003#)
 在Java程式只需使用Statement物件的
executeUpdate()方法執行SQL指令就可以插入一
筆圖書記錄,如下所示:
Ch15_4.stmt.executeUpdate(strSQL);

範例1:新增一筆資料
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
import java.sql.*;
class Ch03_01
{
public static void main(String [] args)
{
//開啟資料庫連結
//連結資料庫
//步驟1:載入驅動程式
Ch03_DB.load_Driver();
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch03_DB.connect_DBObject(sCon);
//步驟3:執行SQL指令
try
{
String strSQL = "INSERT INTO Book "
+ "(BookID, BookTitle, BookAuthor, BookPrice, BookPubDate) "
+ "VALUES ('D0003', 'Test3', 'WANG', 550.0, #2007/03/25#)";
Ch03_DB.stmt.executeUpdate(strSQL);
String out = Ch03_DB.execute_SQL("SELECT * FROM Book");
System.out.println(out);
}
catch (SQLException e)
{ System.out.println(e.getMessage()); }
finally
{ Ch03_DB.close_DB();
}
}
}
更新記錄-說明
SQL語言更新記錄指令UPDATE是將資料表內符合條
件的記錄,都更新成指定的欄位值,UPDAT E指令
的語法格式,如下所示:
UPDATE table SET column1 = ‘value1’ WHERE
conditions
 table是資料表,SET子句column1是資料表的欄位
名稱,這是需要更新的欄位,value1是更新的欄
位值,如果更新欄位不只一個,請使用逗號分隔
,其語法格式,如下所示:
UPDATE table SET column1 = 'value1' , column2
= 'value2' WHERE conditions

更新記錄-注意事項
WHERE子句是必要元素,如果沒有WHERE子句
,資料表內所有記錄欄位都會被更新。
 更新欄位值是數值不用單引號包圍,字元需
要使用單引號包圍,日期時間為”#”符號。

更新記錄-範例

例如:在資料表Book更改記錄圖書資料的SQL
指令,如下所示:
UPDATE Book SET BookPrice=580.0,
BookPubDate=#8/8/2003#
WHERE BookID='L333'

上述SQL指令的WHERE條件為圖書書號BookID欄
位,使用SET子句更新欄位資料。
範例2:修改資料
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
import java.sql.*;
class Ch03_02
{
public static void main(String [] args)
{
//開啟資料庫連結
//連結資料庫
//步驟1:載入驅動程式
Ch03_DB.load_Driver();
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch03_DB.connect_DBObject(sCon);
//步驟3:執行SQL指令
try
{
String strSQL = "UPDATE Book "
+ "SET BookTitle='Test1', BookAuthor='LIN', BookPrice=500 "
+ "WHERE BookID='D0001'";
Ch03_DB.stmt.executeUpdate(strSQL);
String out = Ch03_DB.execute_SQL("SELECT * FROM Book");
System.out.println(out);
}
catch (SQLException e)
{ System.out.println(e.getMessage()); }
finally
{ Ch03_DB.close_DB();
}
}
}
刪除記錄-說明

SQL語言刪除記錄指令DELETE是將資料表內符
合條件的記錄通通刪除掉。DELETE指令的語
法格式,如下所示:
DELETE FROM table WHERE conditions

table是資料表,WHERE子句conditions為刪
除記錄的條件,口語來說是「將符合
conditions條件的記錄刪除掉」。
刪除記錄-注意事項與範例

DELETE指令的注意事項,如下所示:


WHERE子句是DELETE指令的必要元素,如果沒有
WHERE子句,資料表內的所有記錄都會被刪除。
例如:在資料表Book刪除一筆圖書記錄的SQL
指令,如下所示:
DELETE FROM Book WHERE BookID='L333'
範例3:刪除記錄
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
import java.sql.*;
class Ch03_03
{
public static void main(String [] args)
{
//開啟資料庫連結
//連結資料庫
//步驟1:載入驅動程式
Ch03_DB.load_Driver();
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch03_DB.connect_DBObject(sCon);
//步驟3:執行SQL指令
try
{
String strSQL = "DELETE FROM Book "
+ "WHERE BookID='D0003'";
Ch03_DB.stmt.executeUpdate(strSQL);
String out = Ch03_DB.execute_SQL("SELECT * FROM Book");
System.out.println(out);
}
catch (SQLException e)
{ System.out.println(e.getMessage()); }
finally
{ Ch03_DB.close_DB();
}
}
}
可更新ResultSets

要讓游標可以前後移動,在
connection.createStatement()時就要指定
public Statement createStatement() throws
SQLException
 Public Statement createStatement(int sType,
int sConcurrency) throws SQLException

 sType:



指定ResultSet可否捲動,其常數有
TYPE_FORWARD_ONLY:不可捲動,只可向前
TYPE_SCROLL_INSENITIVE: 可捲動,無法立刻看到更新結果
TYPE_SCROLL_SENSITIVE:可捲動,並可立刻看到更新結果
 sConcurrency:


指定ResultSet是唯讀或可更新
CONCUR_READ_ONLY
CONCUR_UPDATABLE
可更新的ResultSet
可更新的ResultSet物件不需要是可捲動的
 有了UpdatableResultSet物件,可以插入一個
新的資料列,刪除既有的資料列,或是修改一
個以上的欄位值
 可是,請求一個UpdatableResultSet並不保證
可以得到,要看我們使用的驅動程式而定。可
以用ResultSet.getConcurrency()來查證
ResultSet是否可更動

範例4:測試ResultSet是否可更動
1.
import java.sql.*;
2.
class Ch03_04
{
public static void main(String [] args)
{
//開啟資料庫連結
//連結資料庫
//步驟1:載入驅動程式
Ch03_DB.load_Driver();
//步驟2:建立Connection連結物件
String sCon = "jdbc:odbc:java4_Ch01";
Ch03_DB.connect_DBObject(sCon);
//步驟3:執行SQL指令
try
{
ResultSet rs = Ch03_DB.execute_SQL_RS("SELECT * FROM Book");
if(rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE)
System.out.println("UPDATABLE");
else
System.out.println("READ_ONLY");
}
catch (SQLException e)
{ System.out.println(e.getMessage()); }
finally
{ Ch03_DB.close_DB();
}
}
}
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
更新ResultSet

方法1:利用SQL語言中的UPDATE:
Stmt.executeUpdate(
“UPDATE bookITEM SET 書名 = ‘ASPNET應用’ WHERE 編號 =
1004”);
 困難度高,試想在視窗的環境中(上一章的範例2及練習),我們可能只
知道目前指標在資料庫的位置,要取得WHERE的條件可能很難

方法2:將指標移到要更新的資料項上,執行:
rs.updateString(“書名”, “ASPNET應用”);
 要注意一定要將指標移到要更新的資料上

使用方法2時,一定要在修改後,移動游標之前,做:


rs.updateRow();
讓更新後的資料,真的有效
在呼叫updateRow()之前可以呼叫cancelRowUpdates()
來取消更新
Update()方法:與getter()類似
資料型別
方法
boolean
updateBoolean(String columnName, boolean x)
byte
updateByte(String columnName, byte x)
byte[]
updateBytes(String columnName, byte[] x)
double
updateDouble(String columnName, double x)
float
updateFloat(String columnName, float x)
int
updateInt(String columnName, int x)
long
updateLong(String columnName, long x)
short
updateShort(String columnName, short x)
String
updateString(String columnName, String x)
java.sql.Date
updateDate(String columnName, Date x)
Java.sql.Time
updateTime(String columnName, Time x)
Java.sql.Timestamp updateTimestamp(String columnName, Timestamp x)
NULL
updateNull(String columnName)
Java.io.InputStrea
m
updateAsciiStream(String columnName, InputStream x,
int length)
Java.io.InputStrea
getUnicodeStream(String columnName, InputStream x,
插入新的資料列
1.
2.
3.

將游標移到要插入的資料列上,利用呼叫
moveToInsertRow()方法來完成
利用適當的更新方法來設定資料列上每一個
欄位的新數值
呼叫insertRow()方法將新資料列插入到結果
集合,並且同時加入到資料庫中
記得在移動游標到其他記錄之前,一定要做
第3步,否則,所有的新增動作是白作的
刪除資料列

將游標移到想刪除的資料上,並呼叫
deleteRow()方法
看到ResultSet中的更動
所謂更動可被看見指的是所更動的值可在進行
更動後利用呼叫適當的getter方法來取出
 要是getter方法仍傳回原先的欄位數值的話,
那更動就是不可見的
 當關閉這個不可被看見更動的ResultSet後,
再重新執行一次相同的查詢,就可以看到更動
後的結果;或是在更動後的資料列上呼叫
refreshRow()方法

範例2:新增 刪除 修改
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.

if(e.getSource() == tf_編號)
{
rs.updateInt("編號", Integer.parseInt(tf_編號
.getText()));
rs.updateRow();
}
else if(e.getSource() == tf_書名)
{
rs.updateString("書名", tf_書名.getText());
rs.updateRow();
}
else if(e.getSource() == tf_作者)
{
rs.updateString("作者", tf_作者.getText());
rs.updateRow();
}
else if(e.getSource() == tf_書價)
{
rs.updateInt("書價", Integer.parseInt(tf_書價
.getText()));
rs.updateRow();
}
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
if(按鈕標記.equals("新增"))
{
rs.moveToInsertRow();
rs.updateInt("編號",0);
rs.updateString("書名", " ");
rs.updateString("作者", " ");
rs.updateInt("書價", 0);
rs.insertRow();
rs.last();
}
else if(按鈕標記.equals("刪除"))
{
rs.deleteRow();
rs = stmt.executeQuery(query);
rs.first();
}
預存陳述句PreparedStatement
PreparedStatements 是預先編譯過的陳句,
它比一般陳述句執行起來更有效率,尤其是當
要在迴圈中執行陳述句
 PreparedStatements具有用來保存變數的輸入
參數:

pstmt.setInt(1,2); //將第一個參數設為整數值2
範例3:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
java.sql.*;
public class Ex04_06
{
public static void main(String args[])
{
int b_no;
String b_name;
String b_auth;
int b_price;
13.
14.
15.
16.
17.
18.
19.
20.
21.
String query = "SELECT 編號, 書名, 作
者, 書價 FROM bookITEM WHERE b_no =?";
…
catch(ClassNotFoundException e)
{ e.printStackTrace(); }
catch(SQLException e)
{ e.printStackTrace(); }
}
}
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver
");
Connection con =
DriverManager.getConnection("jdbc:odbc:Ch04
Book");
PreparedStatement pstmt =
con.prepareStatement(query);
pstmt.setInt(1 , 2);
//pstmt.setInt(2,0);
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
b_no = rs.getInt("編號");
b_name = rs.getString("書名");
b_auth = rs.getString("作者");
b_price = rs.getInt("書價");
System.out.println(b_no + "\t" + b_name +
"\t" +b_auth + "\t" + b_price);
練習1

設計一個查詢畫面,可供使用者在任一欄位上
輸入查詢條件, 並呈現查詢結果
Ch04 資料庫專案範例
JAVA程式語言(4)
專案實例:圖書資料管理系統
圖書資料管理系統的架構
 圖書資料管理系統的編譯與執行
 Java程式說明

2015/7/20
105
圖書資料管理系統的架構-說明

圖書資料管理系統使用



Access資料庫Books.mdb
使用介面是第11章JInternetFrame類別的多重視窗
JOptionPane類別的訊息對話方塊。
在圖書資料管理系統使用功能表列的指令執行資
料庫操作和搜尋,使用者並不需要下達完整的SQL
指令,就可以新增、更新、刪除和以書號查詢圖
書記錄,搜尋記錄功能可以讓使用者輸入完整的
SQL查詢指令,其中每一種功能都擁有獨立的內層
視窗,使用者可以同時開啟多個視窗執行不同的
圖書資料查詢。
2015/7/20
106

InternalFrame類別
多重視窗介面InternalFrame類別
 建構子InternalFrame(String, boolean,
boolean, boolean, boolean)

第1個參數是視窗標題
 第2個參數是可調整尺寸
 第3個參數是可關閉
 第4個參數是可最大化
 第5個參數是可縮小
 第2,3,4,5參數預設值為false

2015/7/20
107
圖書資料管理系統的架構-Java
程式說明
Java 程式
Books.java
JDBC.java
AddRecord.java
DeleteRecord.java
SQLQuery.java
IdQuery.java
2015/7/20
說明
圖書資料管理系統的主程式,這是 JFrame 的
Swing 應用程式,擁有功能表列和各種功能指
令,處理各功能內層視窗的建立
類似 Ch15_4.java 的 JDBC 相關類別方法
JInternalFrame 內層視窗類別,用來新增圖書資
料
JInternalFrame 內層視窗類別,只需輸入書號就
可以刪除圖書資料
JInternalFrame 內層視窗類別,可以執行 SQL 查
詢指令
JInternalFrame 內層視窗類別,可以使用書號查
詢圖書資料
108
圖書資料管理系統的編譯與執
行
2015/7/20
109
Java程式說明-Books.java
Books.java
 Books.java程式是修改自Ch11_5.java的多
重視窗應用程式,直接擴充
createMenuBar()方法的功能表列,新增功
能表指令來開啟不同JInternalFrame類別
的內層視窗。
 在其中的createInternalFrame()方法可以
建立內層視窗,資料庫操作的addFrame和
deleteFrame視窗物件都只能建立一次。
2015/7/20
110
Java程式說明-Books.java
使用if條件檢查內層視窗是否已經建立,如下所
示:
if (addFrame == null)
{ // 第一次建立
addFrame = new AddRecord();
jdesktop.add(addFrame);
}
else if (addFrame.isClosed())
{ // 內層視窗被關閉
addFrame = new AddRecord();
jdesktop.add(addFrame);
2015/7/20}
111

Java程式說明-Books.java

如果內層視窗已經建立,因為使用者可能縮小
視窗成為圖示,所以使用isIcon()方法檢查是
否為圖示顯示,setIcon(false)方法將它設成
不是圖示顯示,如下所示:
if (iframe.isIcon())
iframe.setIcon(false);
2015/7/20
112
Java程式說明-JDBC.java
JDBC.java
 JDBC.java就是Ch15_4.java,只是更改類別名
稱,內含JDBC驅動程式的載入、建立和關閉
ODBC資料庫連結的方法。
2015/7/20
113
Java程式說明AddRecord.java
AddRecord.java
 AddRecord.java是繼承JInternalFrame類別的
內層視窗類別,在建立好輸入欄位資料的
JTextField元件後,直接使用Ch15_5_1.java
的SQL指令來新增記錄。
2015/7/20
114
Java程式說明AddRecord.java

按鈕的事件處理方法actionPerformed()在
新增記錄前會查詢書號,以確認書號是否
已經存在,如下所示:
String code = id.getText();
String strSQL = "SELECT * FROM Book WHERE
BookID='" + code + "'";
rs = JDBC.stmt.executeQuery(strSQL);
int count = 0;
while ( rs.next() ) // 是否有此記錄
count++;
2015/7/20
115
Java程式說明AddRecord.java

新增記錄的出版日期就是今天,這是使用
System類別的currentTimeMillis()方法取得
的Date日期物件,如下所示:
Date pubDate = new
Date(System.currentTimeMillis());
2015/7/20
116
Java程式說明DeleteRecord.java
DeleteRecord.java
 DeleteRecord.java是繼承JInternalFrame類
別的內層視窗類別,在建立好輸入書號欄位資
料的JTextField元件後,使用Ch15_5_3.java
的SQL指令刪除記錄,在刪除記錄前會查詢書
號,以確認刪除書號存在。
2015/7/20
117
Java程式說明-SQLQuery.java
SQLQuery.java
 SQLQuery.java就是第15-4-3節的
Ch15_4_3.java,只是改成繼承
JInternalFrame類別的內層視窗類別。
2015/7/20
118
Java程式說明-IdQuery.java
IdQuery.java
 idQuery.java和SQLQuery.java相似,只是SQL
指令改成書號的萬用字元條件,如下所示:
String strSQL;
strSQL="SELECT * FROM Book WHERE BookID LIKE
'%"+code+"%'";
2015/7/20
119