国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
在 Eclipse 中開發(fā) Apache Derby 應(yīng)用程序

在 Eclipse 中開發(fā) Apache Derby 應(yīng)用程序

級別: 初級

Gilles Roux (groux@us.ibm.com), 信息管理軟件工程師, IBM

2005 年 2 月 01 日

在開發(fā) Apache Derby 應(yīng)用程序的過程中需要執(zhí)行很多任務(wù),例如創(chuàng)建和連接數(shù)據(jù)庫,編寫 Java? JDBC 客戶機(jī)應(yīng)用程序和存儲過程,以及將最終得到的軟件組件部署到生產(chǎn)環(huán)境。本文旨在發(fā)現(xiàn)如何結(jié)合使用各種基于 Eclipse 的 Apache Derby 工具來簡化這一開發(fā)過程。

概述

本文的目的是向您展示如何在 Eclipse 集成開發(fā)環(huán)境(IDE)中使用幾種不同的工具,例如 Java Development Tools、IBM? DB2? plug-ins for Eclipse 和 IBM integration plug-in for Derby,以便開發(fā) Apache Derby 應(yīng)用程序。

本文將介紹一個典型 Derby 應(yīng)用程序的整個開發(fā)周期,從數(shù)據(jù)庫的創(chuàng)建開始,然后經(jīng)歷 JDBC 客戶機(jī)應(yīng)用程序的開發(fā),存儲過程和函數(shù)的開發(fā),最后是解決方案的開發(fā)。本文還將描述必要時如何用 DB2 Universal Database (UDB) 數(shù)據(jù)庫替代 Apache Derby 數(shù)據(jù)庫。

本文假設(shè)您對 Apache Derby 數(shù)據(jù)庫、Eclipse 平臺和 DB2 plug-ins for Eclipse 有基本的理解。強(qiáng)烈建議您閱讀 參考資料 一節(jié)中列出的文章“與 Apache Derby 一起使用 DB2 plug-ins for Eclipse”的兩個部分。

為了闡明應(yīng)用程序開發(fā)中涉及的各種不同任務(wù),作者 Gilles Roux 將提供關(guān)于如何構(gòu)建一個示例應(yīng)用程序的具體例子和逐步說明。

在這個例子中,您需要開發(fā)一個命令行應(yīng)用程序來執(zhí)行一家書店的庫存管理。書店的數(shù)據(jù)庫存儲了這家書店擁有的各種書籍,以及這些書籍的現(xiàn)有數(shù)量。

這個示例應(yīng)用程序?qū)⒃试S您訪問這些數(shù)據(jù),并允許您更改書籍的數(shù)量。例如,如果從一個供應(yīng)商那里收到一批書,那么就要使用這個應(yīng)用程序來添加所收到書籍的數(shù)量。如果書籍的數(shù)量超過或者低于某個限制,則需要用電子郵件通知管理員,以便其采取必要的行動。

開發(fā)環(huán)境

工具

Java Development Tools(JDT)是一組內(nèi)建到 Eclipse 中的插件,為編輯、編譯、調(diào)試、執(zhí)行和部署一般用途的 Java 應(yīng)用程序提供了一種方法。

DB2 plug-ins for Eclipse 提供了連接到各種數(shù)據(jù)庫(包括 IBM Cloudscape 和 Apache Derby)的一組功能。這個插件是以下幾個插件的組合。

  • Connection Wizard:用于創(chuàng)建和連接 DB2、Cloudscape 或 Derby 數(shù)據(jù)庫。
  • Database Explorer View:用于瀏覽數(shù)據(jù)庫對象。
  • SQL Scrapbook:用于編輯和執(zhí)行單獨(dú)的 SQL 語句。
  • Database Output View:用于對一個表的內(nèi)容進(jìn)行抽樣或者查看一條 SQL 語句的執(zhí)行結(jié)果。
  • Migration Wizard:用于自動地將一個現(xiàn)有 Derby 數(shù)據(jù)庫遷移到 DB2 UDB。

 

IBM integration plug-in for Derby 將很多有用的 Derby 工具集成到了 Eclipse 環(huán)境中。下面是該工具所提供的主要功能:

  • Apache Derby Nature:使 Eclipse 項(xiàng)目可以執(zhí)行 Derby 任務(wù)。
  • Network Server:直接從 Eclipse 項(xiàng)目中配置和啟動 Derby Network Server。
  • IJ:直接在 Eclipse 控制臺中以交互模式或腳本模式啟動 Derby 命令行實(shí)用程序。
  • Sysinfo:顯示與項(xiàng)目相關(guān)的 Derby 系統(tǒng)信息。

 

DB2 plug-ins for Eclipse 和 IBM Integration plug-in for Derby 是兩個獨(dú)立的工具,但是它們之間互補(bǔ)性很強(qiáng),前者提供了一般數(shù)據(jù)庫連接,而后者則提供了訪問很多特定于 Derby 特性的訪問途徑。

然而,很多任務(wù)都可以通過這些工具中的任意一個來執(zhí)行,效果是一樣的。本文提到了執(zhí)行一個給定任務(wù)的各種不同方法,從而使每個用戶都可以選擇他們所喜愛的工作方式。

安裝工具

首先要下載和安裝 DB2 plug-ins for Eclipse。該產(chǎn)品包括 DB2 插件,并且是基于 Eclipse 3.0 的,后者本身就包括了 JDT。

然后從 Apache.org 下載 Apache Derby plug-in,并在安裝了前面軟件的基礎(chǔ)上安裝此軟件。

最后,下載 IBM Integration plug-in for Derby 并在安裝了 eclipse 的基礎(chǔ)上安裝此軟件。該插件包括 JCC JDBC 驅(qū)動程序和 Derby 集成工具。

設(shè)置開發(fā)環(huán)境

如前所述,您將使用幾種不同的工具來開發(fā)應(yīng)用程序:DB2 plug-ins for Eclipse、IBM Integration plug-in for Derby 和 JDT。這些工具都是基于 Eclipse 的,因此它們可以很好地集成到一個單獨(dú)的開發(fā)環(huán)境中。

在開發(fā)應(yīng)用程序時,通常要建立一些到數(shù)據(jù)庫的連接:

  • 使用 Database Explorer 瀏覽數(shù)據(jù)庫。
  • 使用 Derby ij 命令行實(shí)用程序執(zhí)行 SQL 語句。
  • 在測試時應(yīng)用程序自己將連接到數(shù)據(jù)庫。

 

Derby 數(shù)據(jù)庫引擎可以在多種配置下運(yùn)行。最簡單的一種是嵌入式配置,但在這里不適合,因?yàn)樾枰ㄟ^運(yùn)行在不同 Java 虛擬機(jī)上的幾種工具建立連接。而且,在生產(chǎn)環(huán)境中,可能需要從多個應(yīng)用程序中訪問數(shù)據(jù)庫。因此,這里使用 Network Server 配置。IBM Integration plug-in for Derby 提供了一種選擇,以便可以很容易地從 Eclipse 項(xiàng)目目錄中啟動本地機(jī)器上的 Derby Network Server。接著要配置應(yīng)用程序和其他工具,以連接到該網(wǎng)絡(luò)服務(wù)器。下圖展示了配置情況。


圖 1. 開發(fā)環(huán)境配置

設(shè)置環(huán)境的第一步是創(chuàng)建項(xiàng)目。選擇“File->New->Project->Java Project”并輸入 bookstore 作為項(xiàng)目名稱。這樣就創(chuàng)建了一個 Java 項(xiàng)目,然后切換到 Java perspective(透視圖)中。右擊該項(xiàng)目并選擇“Apache Derby->Add Apache Derby nature”。這樣使您的項(xiàng)目可以使用 Apache Derby 特性,然后設(shè)置該 Java 項(xiàng)目的構(gòu)建路徑,以便應(yīng)用程序可以訪問 Derby 數(shù)據(jù)庫和 JDBC 驅(qū)動程序。

DB2 plug-ins for Eclipse 通??梢詮?Data perspective 訪問,并且無需與某個特定的項(xiàng)目相關(guān)聯(lián)。為了簡化開發(fā)過程,避免 Java perspective 和 Data perspective 之間的切換,需要將 DB2 plug-ins 視圖,即 Database Explorer 視圖和 DB Output 視圖,添加到 Java perspective。這可以通過 Show View->Other 菜單來完成。下圖展示了開發(fā)環(huán)境的外觀。


圖 2. 開發(fā)環(huán)境布局
 

創(chuàng)建數(shù)據(jù)庫

在開始編寫實(shí)際的應(yīng)用程序代碼之前,需要創(chuàng)建應(yīng)用程序?qū)⒁玫降臄?shù)據(jù)庫,或者連接到一個已有的數(shù)據(jù)庫。

首先通過右擊項(xiàng)目并選擇“Apache Derby->Start Derby Network Server”來啟動 Derby Network Server。每次重新啟動 Eclipse 時都需要執(zhí)行這一步。這時項(xiàng)目圖標(biāo)上有一個綠色的箭頭,表明服務(wù)器正在運(yùn)行。

創(chuàng)建數(shù)據(jù)庫

創(chuàng)建一個 Derby 數(shù)據(jù)庫非常類似于連接到一個已有的數(shù)據(jù)庫:通過將 create=true 屬性包括在 URL 中,可以指示數(shù)據(jù)庫引擎在您第一次連接到數(shù)據(jù)庫時創(chuàng)建該數(shù)據(jù)庫。這可以通過使用 DB2 plug-ins for Eclipse 的 Connection Wizard 來完成。下面的表展示了在這個向?qū)е袘?yīng)該使用的參數(shù)。

表 1. 連接參數(shù)

Connection name bookstoredb
Database Manager Apache Derby v10.0
JDBC Driver IBM DB2 Universal 需要使用這個參數(shù)來連接到網(wǎng)絡(luò)服務(wù)器
Database bookstoredb 要創(chuàng)建的數(shù)據(jù)庫的名稱
Host localhost 網(wǎng)絡(luò)服務(wù)器運(yùn)行在本地機(jī)器上
Port Number 1527 默認(rèn)端口號
Class Location 比如: C:\eclipse\plugins\ com.ibm.cloudscape.ui_1.0.0\db2jcc_license_c.jar;C:\eclipse\plugins\com.ibm.cloudscape.ui_1.0.0 \db2jcc.jar
Create database if required yes 需要使用這個參數(shù)在第一次連接時創(chuàng)建數(shù)據(jù)庫
User ID bookstore 數(shù)據(jù)庫上的認(rèn)證沒有被啟用,因此可以使用任何用戶,但是用戶名將定義默認(rèn)模式
Password aaa 數(shù)據(jù)庫上的認(rèn)證沒有被啟用,因此可以使用任何密碼


圖 3. 使用 Connection Wizard 創(chuàng)建數(shù)據(jù)庫

完成該向?qū)Ш?,便?chuàng)建了一個數(shù)據(jù)庫,并且向 Database Explorer View 中添加了一個連接。通過展開連接的節(jié)點(diǎn),就可以瀏覽這個數(shù)據(jù)庫,但是顯然這個時候它是空的。

數(shù)據(jù)庫被創(chuàng)建在 Derby 網(wǎng)絡(luò)服務(wù)器的當(dāng)前目錄中,也就是之前創(chuàng)建 Eclipse 項(xiàng)目時所在的目錄??梢酝ㄟ^右擊項(xiàng)目名并選擇 Refresh 來刷新該項(xiàng)目,這樣將顯示一個新的 bookstoredb/ 目錄,該目錄包含用于數(shù)據(jù)庫的文件。不要試圖修改這些文件,否則數(shù)據(jù)庫會受到損壞。

創(chuàng)建數(shù)據(jù)庫對象

接下來的步驟是創(chuàng)建應(yīng)用程序?qū)⒁玫降臄?shù)據(jù)庫對象。在這里,只需使用 SQL Scrapbook 創(chuàng)建一個表即可。SQL Scrapbook 可以通過右擊連接名并選擇“Open SQL Scrapbook”來調(diào)用。這時將打開一個新的編輯器,在這個編輯器中可以輸入要發(fā)出的 SQL 語句:


清單 1. CREATE TABLE 語句
                                create table books(                                id int,                                title varchar(128),                                author varchar(128),                                price decimal(6,2),                                quantity int,                                status int                                )                                

請注意,SQL Scrapbook 只能用于執(zhí)行單條的 SQL 語句。而且,不要以分號來結(jié)束 SQL 語句。然后,可以按下主 Eclipse 按鈕欄中的“Execute SQL statement”按鈕。DB Output 視圖應(yīng)該顯示結(jié)果是成功的。還可以刷新連接,以及驗(yàn)證數(shù)據(jù)庫現(xiàn)在是否包含新創(chuàng)建的表。


圖 4. 使用 SQL Scrapbook 創(chuàng)建表

創(chuàng)建測試數(shù)據(jù)

現(xiàn)在通過執(zhí)行 INSERT 語句向 books 表填充一些測試數(shù)據(jù)。這也可以通過 SQL Scrapbook 來實(shí)現(xiàn),但這里我們使用了 IBM Integration plug-in for Derby 的“Run SQL script using ij”功能。這項(xiàng)功能允許使用 Derby 命令行實(shí)用程序執(zhí)行 SQL 腳本,并在 Eclipse 輸出視圖中查看結(jié)果。這種方法的一大優(yōu)點(diǎn)是:它允許一次執(zhí)行多條語句。而且,這種方法要求在腳本的開始處包含一條連接語句,因此您可以對連接 URL 有更多的控制。

表 2. SQL Scrapbook 和 IJ 腳本 之間的不同之處

SQL Scrapbook 執(zhí)行 IJ 腳本
語句存儲在一個文件中 不是
一次可以執(zhí)行多條語句 不是
語句終止符 不允許有終止符 分號
編輯功能 語法高亮顯示,內(nèi)容輔助 沒有
到數(shù)據(jù)庫的連接 SQL scrapbook 被關(guān)聯(lián)到一個給定的連接 第一條語句應(yīng)該是到所需數(shù)據(jù)庫的一個連接

構(gòu)建 URL 的一種簡便方法是復(fù)制 Connection Wizard 所使用的 URL:在數(shù)據(jù)庫瀏覽器中右擊連接,然后選擇“Edit Connection”并訪問“Connection URL”字段。這里需要添加用戶名和密碼作為 URL 屬性。

使用 Eclipse 在項(xiàng)目中創(chuàng)建一個名為 data.sql 的文本文件,并鍵入以下命令:


清單 2. INSERT INTO 語句
                                connect 'jdbc:derby:net://localhost:1527/bookstoredb:user=bookstore;password=aaa;';                                insert into books values(1, 'East Of Eden', 'John Steinbeck', 7.20, 3, 0);                                insert into books values(2, 'Hard-Boiled Wonderland and the End of the World',                                'Haruki Murakami', 10.50, 9, 0);                                insert into books values(3, 'SQL for Dummies', 'Allen G. Taylor', 16.49, 6, 0);                                disconnect;                                

然后就可以在 Project Explorer 中右擊該文件并選擇“Apache Derby->Run SQL script using ij”。Eclipse 的控制臺輸出視圖將顯示執(zhí)行的結(jié)果,這個結(jié)果應(yīng)該是成功的。然后可以在 Database Explorer 中選擇 books 表,并選擇“Sample Content”,以確信數(shù)據(jù)真正被插入到這個表中。


圖 5. 執(zhí)行 SQL 腳本以插入數(shù)據(jù)
 

編寫 Derby Client JDBC 應(yīng)用程序

裝載 JDBC 驅(qū)動程序

通過使用 Eclipse JDT 和 Derby JDBC 驅(qū)動程序,可以很容易地編寫 JDBC 應(yīng)用程序。首先使用 JDT Class 向?qū)г?bookstoreapp.clientside 包中創(chuàng)建一個 Inventory 類,并在類中添加一個 main() 方法。由于啟用了 Derby nature,所以包含 JDBC 驅(qū)動程序和 Derby 類的 JAR 文件已經(jīng)位于項(xiàng)目的類路徑中。

在連接到一個 Derby 數(shù)據(jù)庫之前,需要使用 Class.forName(jdbcDriverClassName) 方法裝載適當(dāng)?shù)?JDBC 驅(qū)動程序。該方法將裝載參數(shù)指定的 JDBC Driver 類,并注冊這個類,以便進(jìn)行下一次 JDBC 連接。

可以使用兩種不同的 JDBC 驅(qū)動程序,這取決于 Derby 配置:

表 3. Derby JDBC 驅(qū)動程序

配置 Embedded Server Network Server
所需 JAR 文件 derby.jar db2jcc.jar;db2jcc_license_c.jar
類名 org.apache.derby.jdbc.EmbeddedDriver com.ibm.db2.jcc.DB2Driver

由于這個例子是基于一個網(wǎng)絡(luò)服務(wù)器配置,因此這里使用 jcc JDBC 驅(qū)動程序。如果不確定的話,那么正確的類名可以通過從 Connection 向?qū)?fù)制獲得:


清單 3. 裝載 jcc JDBC 驅(qū)動程序
                                Class.forName("com.ibm.db2.jcc.DB2Driver");                                

連接到數(shù)據(jù)庫

DriverManager.getConnection(url) 方法用于建立到數(shù)據(jù)庫的連接。它假設(shè)一個連接 URL,并返回一個 Connection 對象,這個對象可用于查詢數(shù)據(jù)庫。

獲得連接 URL 的一種好方法是在 Database Explorer 視圖中編輯 Derby 連接,并復(fù)制從各個連接屬性自動構(gòu)造而成的連接 URL。出于安全的原因,這里沒有顯示用戶名和密碼,因此在應(yīng)用程序代碼中需要手動地將它們添加到 URL 的后面。


圖 6. 使用連接向?qū)?gòu)建連接 URL

其他選項(xiàng)也可以添加到 URL 的后面。例如,retrieveMessagesFromServerOnGetMessage=true 選項(xiàng)指示 JDBC 驅(qū)動程序從 Derby 服務(wù)器獲取可讀的錯誤消息,這在調(diào)試連接到遠(yuǎn)程 Derby 數(shù)據(jù)庫的應(yīng)用程序時非常有用。

在本文的例子中,使用下列代碼連接到 Derby 數(shù)據(jù)庫:


清單 4. 連接到數(shù)據(jù)庫
                                String url = "jdbc:derby:net://localhost:1527/bookstoredb";                                url += ":user=bookstore;password=aaa;";                                url += "retrieveMessagesFromServerOnGetMessage=true;";                                Connection con = DriverManager.getConnection(url);                                

查詢數(shù)據(jù)庫

一旦建立了連接,便可以通過使用 JDBC API 查詢數(shù)據(jù)庫。例如,您可以創(chuàng)建一個 Statement 對象,然后使用這個對象來執(zhí)行對數(shù)據(jù)庫的 SQL 查詢。查詢返回一個用于迭代查詢結(jié)果集的 ResultSet 對象:


清單 5. 執(zhí)行查詢并迭代結(jié)果集
                                Statement stmt = con.createStatement();                                ResultSet rs = stmt.executeQuery("SELECT * FROM bookstore.books");                                while (rs.next()) {                                System.out.print(rs.getString(1) + ", ");                                System.out.print(rs.getString(2) + ", ");                                System.out.print(rs.getString(3) + ", ");                                System.out.print(rs.getString(4) + ", ");                                System.out.print(rs.getString(5) + ", ");                                System.out.println(rs.getString(6));                                }                                rs.close();                                stmt.close();                                


圖 7. 運(yùn)行 JDBC 應(yīng)用程序

要了解關(guān)于使用 JDBC 的更多信息,請參閱本文 參考資料 一節(jié)中列出的 JDBC 教程。

您可以下載 Inventory 類的完整代碼。這個類實(shí)現(xiàn)了一個簡單的文本界面,用于列出書店中的書籍以及更新書店中給定的某種書籍的數(shù)量。

下面是應(yīng)用程序輸出的一個例子:


圖 8. Inventory 應(yīng)用程序的示例輸出
 

編寫 Java 函數(shù)和過程

前一節(jié)中討論的 JDBC 應(yīng)用程序?qū)τ陂_發(fā)用于用戶的前端應(yīng)用程序非常有用。然而,在這一層中實(shí)現(xiàn)重要的應(yīng)用程序邏輯不是很妥當(dāng),因?yàn)閼?yīng)用程序邏輯放置在數(shù)據(jù)庫之外,這使得數(shù)據(jù)庫更容易受到損壞。例如,如果另一個 JDBC 應(yīng)用程序連接到同一個數(shù)據(jù)庫,那么就需要確保它實(shí)現(xiàn)相同的邏輯。對于這個問題,一種解決辦法是通過使用觸發(fā)器、存儲過程和函數(shù),在數(shù)據(jù)庫中實(shí)現(xiàn)數(shù)據(jù)庫規(guī)則。

編寫 Java 代碼

由于 Derby 是一種 Java 數(shù)據(jù)庫,因此它沒有自己的存儲過程/函數(shù)語言,而是使用 Java 語言??梢酝ㄟ^創(chuàng)建一個 Java 方法,然后基于這個 Java 方法聲明一個 Derby 過程或函數(shù),從而創(chuàng)建 Derby 存儲過程或函數(shù)(通常稱為例程)。對 Derby 例程的調(diào)用將導(dǎo)致這個 Java 方法被調(diào)用。

為了讓這種調(diào)用獲得成功,重要的是讓 Derby 和 Java 例程的聲明相匹配。下面的表展示了應(yīng)該使用的 Derby 和 Java 特性的映射。

表 4. 用于編寫 Java 函數(shù)和過程的特性映射

Derby Java
過程 沒有返回值的公共靜態(tài)方法
函數(shù) 有一個返回值的公共靜態(tài)方法
輸入?yún)?shù)(過程或函數(shù)) 方法參數(shù)
輸出參數(shù)(過程) 單入口數(shù)組參數(shù)
輸入/輸出參數(shù)(過程) 單入口數(shù)組參數(shù)
返回值(函數(shù)) 返回值
返回的結(jié)果集 附加的單入口 java.sql.ResultSet[] 參數(shù)

表 5. 用于編寫 Java 函數(shù)和過程的類型映射

Derby Java
SMALLINT short
INTEGER int
BIGINT long
DECIMAL(p,s) java.math.BigDecimal
REAL float
DOUBLE PRECISION double
CHAR(n) String
VARCHAR(n) String
LONG VARCHAR *unsupported*
CHAR(n) FOR BIT DATA byte[]
VARCHAR(n) FOR BIT DATA byte[]
LONG VARCHAR FOR BIT DATA *unsupported*
CLOB(n) *unsupported*
BLOB(n) *unsupported*
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp

對于 Java 方法本身的內(nèi)容沒有約束,因此任何合法的 Java 代碼都可以作為 Derby 過程或函數(shù)來調(diào)用。一種有趣的應(yīng)用是使用標(biāo)準(zhǔn) derby:default:connection URL 建立到 Derby 數(shù)據(jù)庫的 JDBC 連接,以便查詢發(fā)出調(diào)用的數(shù)據(jù)庫。還可以使用完整 JDBC URL 連接到另一個數(shù)據(jù)庫。

對于本文的應(yīng)用程序,需要在 bookstoreapp.serverside 包中創(chuàng)建一個 DerbyFunctions 類,用于容納數(shù)據(jù)庫服務(wù)器將要運(yùn)行的所有 Java 方法。然后可以創(chuàng)建一個 updateQuantity 方法,當(dāng)更新一種書籍的數(shù)量時,將調(diào)用該方法。調(diào)用該方法時需要提供這種書籍的 ID、titleauthor,以及舊的數(shù)量和新的 quantity。這個方法將返回一個整數(shù)值,用于表明是否到達(dá)數(shù)量限制。

因此,這個 Java 方法的聲明如下:


清單 6. Java 方法的聲明
                                public static int updateQuantity(int id, String title, String author,                                int oldQuantity, int newQuantity)                                

這個函數(shù)的作用是:當(dāng)書的數(shù)量達(dá)到一個下界或上界時,就發(fā)送一封電子郵件。因此,可以聲明 LOW_LIMITHIGH_LIMIT 常量,并測試舊的數(shù)量是否低于下界,新的數(shù)量是否高于上界或低于下界。如果條件符合,那么可以調(diào)用另一個負(fù)責(zé)發(fā)送電子郵件的 Java 方法。在這個例子中,只是輸出一條調(diào)試消息,而不發(fā)送真正的電子郵件。

下面是完整的代碼:


清單 7. DerbyFunctions 類
                                package bookstoreapp.serverside;                                public class DerbyFunctions                                {                                public static final int LOW_LIMIT = 2;                                public static final int HIGH_LIMIT = 10;                                public static int updateQuantity(int id, String title, String author,                                int oldQuantity, int newQuantity)                                {                                if ( oldQuantity<HIGH_LIMIT && newQuantity>=HIGH_LIMIT )                                sendEMailAlert("High limit reached", "title: "+title+", author: "+author);                                else if ( oldQuantity>LOW_LIMIT && newQuantity<=LOW_LIMIT )                                sendEMailAlert("Low limit reached", "title: "+title+", author: "+author);                                if (newQuantity>=HIGH_LIMIT)                                return +1;                                else if (newQuantity<=LOW_LIMIT)                                return -1;                                else                                return 0;                                }                                public static void sendEMailAlert(String subject, String msg)                                {                                System.out.println("Sending email: " + subject);                                System.out.println(msg);                                }                                }                                

從 main 方法中調(diào)用這個 Java 方法,以便對其進(jìn)行測試,這通常是一種很好的做法。

創(chuàng)建 Derby 函數(shù)

創(chuàng)建 Derby 存儲過程或函數(shù)比較容易,只需指定名稱、參數(shù)、返回值和相應(yīng) Java 方法的全限定名稱即可。Derby 例程的標(biāo)簽必須與 Java 方法的標(biāo)簽相匹配,以便數(shù)據(jù)庫可以成功地調(diào)用 Java 代碼。

可以很容易地從 SQL Scrapbook 發(fā)出 CREATE 語句,但是在這個例子中,最好使用 ij 實(shí)用程序。如果使用 ij 實(shí)用程序,便可以顯式地指定連接 URL,從而允許我們包括 retrieveMessagesFromServerOnGetMessage=true 屬性。該選項(xiàng)導(dǎo)致 JDBC 驅(qū)動程序從服務(wù)器獲取完整的錯誤消息,當(dāng)語句執(zhí)行失敗時,這一點(diǎn)很有幫助。

下面是在 ij 中發(fā)出的命令:


清單 8. 在 Derby 中創(chuàng)建 Java 函數(shù)
                                connect 'jdbc:derby:net://localhost:1527/bookstoredb                                :user=bookstore;password=aaa;retrieveMessagesFromServerOnGetMessage=true;';                                create function updateQuantity(id int, title varchar(128), author varchar(128),                                oldQuantity int, newQuantity int) returns int                                PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA                                EXTERNAL NAME 'bookstoreapp.serverside.DerbyFunctions.updateQuantity';                                

Derby 函數(shù)的創(chuàng)建應(yīng)該可以成功,但有時候我們很難一開始就能保證語句完全正確。下面是可能發(fā)生的一些常見錯誤:

  • ERROR 42962: Long column type column or parameter 'I' not permitted in declared global temporary tables or procedure definitions. 如果使用一種不受支持的參數(shù)類型聲明一個 Derby 過程,就會發(fā)生這種錯誤。
  • ERROR 42X50: No method was found to be able to match method call pack.A.p(int), even tried all combinations of object and primitive types and any possible type conversion for any parameters the method call may have. It may be that the method exists, but it is not public and/or static, or that the parameter types are not method invocation convertible. 當(dāng)調(diào)用一個過程/函數(shù)時,如果 Derby 不能找到與過程/函數(shù)聲明相匹配的 Java 方法,就會發(fā)生這種錯誤。錯誤消息給出了不能找到的 Java 方法的標(biāo)簽。

 

請注意,如果更改了方法的 Java 代碼,那么就需要停止并重新啟動 Derby 網(wǎng)絡(luò)服務(wù)器,以便數(shù)據(jù)庫引擎的類裝載器裝載新的代碼。

成功地創(chuàng)建了 Derby 例程之后,就可以通過 ij 命令行調(diào)用這個例程,以便對其進(jìn)行測試??梢酝ㄟ^使用 CALL 語句來調(diào)用 derby 過程,但在這里因?yàn)樾枰獪y試一個函數(shù),因此發(fā)出以下命令:


清單 9. 調(diào)用 Derby 中的 Java 方法
                                values(updateQuantity(1, 'title', 'author', 5, 15));                                

IJ 顯示返回值,在這里,這個返回值為 1,因?yàn)閿?shù)量到達(dá)了上界。由于這個 Java 方法是在 Derby 服務(wù)器 JVM 中運(yùn)行的,因此調(diào)試消息將被輸出到服務(wù)器的標(biāo)準(zhǔn)輸出中。使用 eclipse 控制臺視圖切換到 Derby 網(wǎng)絡(luò)服務(wù)器控制臺,您應(yīng)該可以看到一條 Sending email... 消息。

還可以嘗試使用以下代碼從 JDBC 應(yīng)用程序中調(diào)用 Derby 函數(shù):


清單 10. 從客戶機(jī)應(yīng)用程序中調(diào)用 Java 方法
                                stmt.executeQuery("values(updateQuantity(1, 'title', 'author', 5, 15)); ");                                

結(jié)果應(yīng)該與前面測試中的結(jié)果一致。

從 Derby 觸發(fā)器中調(diào)用函數(shù)

本節(jié)最后一步是配置 Derby,以便每次更新某種書籍的數(shù)量時,調(diào)用之前定義的函數(shù)。這可以用一個觸發(fā)器來實(shí)現(xiàn)。

derby 觸發(fā)器包含關(guān)于要執(zhí)行的動作以及何時執(zhí)行動作的信息。

表 6. CREATE TRIGGER 語句的子句

INSERT、DELETE 或 UPDATE UPDATE
REFERENCING 子句 OLD AS OLD, NEW AS NEW。為了調(diào)用那個函數(shù),需要能夠引用舊的和新的數(shù)量
FOR EACH 子句 FOR EACH ROW。即使有多行被更新,對函數(shù)的調(diào)用也是逐行進(jìn)行的
動作 update books set status = updateQuantity(…) where id = NEW.id;

下面是在 ij 中發(fā)出的用于創(chuàng)建觸發(fā)器的語句:


清單 11. CREATE TRIGGER 語句
                                create trigger updateQuantityTrig after update of quantity on books                                referencing OLD as OLD NEW as NEW for each row mode db2sql                                update books set status = updateQuantity(NEW.id, NEW.title, NEW.author,                                OLD.quantity, NEW.quantity) where id = NEW.id;                                

檢查觸發(fā)器是否有效的一種簡便方法是使用以下命令從 ij 工具中更新 book 表:update books set quantity=10 where id=1; 對表的修改將觸發(fā)函數(shù)的調(diào)用,從而導(dǎo)致執(zhí)行 Java 方法。這將更新書的狀態(tài),并發(fā)送一條消息,這條消息可以通過切換到網(wǎng)絡(luò)服務(wù)器控制臺視圖來查看。

由于觸發(fā)器直接存儲在數(shù)據(jù)庫中,因此無論如何更新數(shù)據(jù),對觸發(fā)器的調(diào)用都將是一致性的。由于這個原因,如果您試圖使用客戶機(jī)應(yīng)用程序更新數(shù)量,那么您將看到,適當(dāng)?shù)臅r候就會生成電子郵件消息,不需要對應(yīng)用程序作任何更改。

下圖展示了客戶機(jī)應(yīng)用程序的輸出,用的是原始數(shù)據(jù)。注意,這一次書的狀態(tài)會獲得更新,并生成了一條消息:


圖 9. Inventory 應(yīng)用程序的示例輸出


圖 10. Network Server 的示例輸出
 

部署應(yīng)用程序

至此,您已經(jīng)有了一個功能完備的數(shù)據(jù)庫和客戶機(jī)應(yīng)用程序,但它們?nèi)匀恢荒茉?Eclipse 環(huán)境中運(yùn)行,在生產(chǎn)環(huán)境中不被接受。因此,還需要執(zhí)行應(yīng)用程序的部署。

將 Java 函數(shù)存儲在數(shù)據(jù)庫中

如前所述,Derby Java 函數(shù)或過程是由數(shù)據(jù)庫引擎自身來執(zhí)行的。因此,數(shù)據(jù)庫引擎必須能夠訪問 Java 類。在這個例子中,這一點(diǎn)是沒有問題的,因?yàn)?Derby 網(wǎng)絡(luò)服務(wù)器運(yùn)行在 Eclipse 項(xiàng)目中,并且使用項(xiàng)目的類路徑,該類路徑包含了已創(chuàng)建的所有 Java 類。

在一個典型的生產(chǎn)環(huán)境中,您不需要更改用于 Derby 網(wǎng)絡(luò)服務(wù)器的類路徑。Derby 提供了一些可以解決這個問題的過程:

  • sqlj.install_jar 過程將一個 JAR 文件安裝到數(shù)據(jù)庫中。JAR 文件在安裝好之后便無法修改,但是可以使用 sqlj.remove_jarsqlj.replace_jar 來刪除或更新 JAR。
  • derby.database.classpath 屬性包含數(shù)據(jù)庫將要使用的附加類路徑條目??梢酝ㄟ^使用 syscs_util.syscs_set_database_property 過程更新這個屬性,以便更新屬性和包含已安裝的 JAR。

 

對于本文中的例子,首先要創(chuàng)建一個 JAR 文件,這個 JAR 文件包含 DerbyFunctions 類。這可以在 Eclipse 中通過右擊這個類并選擇 Export->JAR file 來完成創(chuàng)建任務(wù)。

然后可以使用下列命令(在 ij 中)將 JAR 文件安裝到數(shù)據(jù)庫中,并將其添加到類路徑中:


清單 12. 將 JAR 文件存儲在 Derby 數(shù)據(jù)庫中
                                CALL sqlj.install_jar('functions.jar', 'bookstore.functionsjar', 0);                                CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(                                'derby.database.classpath', 'bookstore.functionsjar');                                

做完這些后,Java 代碼便屬于數(shù)據(jù)庫,這使得數(shù)據(jù)庫的轉(zhuǎn)移和啟動變得很容易。整個數(shù)據(jù)庫目錄可以直接轉(zhuǎn)移到一個完全不同的環(huán)境中,并且可以正常運(yùn)行。

網(wǎng)絡(luò)服務(wù)器配置

在開發(fā)應(yīng)用程序時,我們使用了網(wǎng)絡(luò)服務(wù)器配置,這樣一來,應(yīng)用程序的部署就會按正確的方式打包各個組件。

在服務(wù)器端,需要安裝:

  • derby.jar,其中包含 Derby 數(shù)據(jù)庫引擎。
  • derbynet.jar,其中包含網(wǎng)絡(luò)服務(wù)器。
  • bookstoredb/ 目錄,其中包含數(shù)據(jù)庫,還包括帶有函數(shù)的 JAR 文件。

 

這些組件可以復(fù)制到任何裝有 JVM 的機(jī)器上,網(wǎng)絡(luò)服務(wù)器可以使用下列命令來啟動:


清單 13. 啟動 Derby 網(wǎng)絡(luò)服務(wù)器
                                java -cp derby.jar;derbynet.jar org.apache.derby.drda.NetworkServerControl start                                

可以使用下列命令可以停止網(wǎng)絡(luò)服務(wù)器:


清單 14. 停止 Derby 網(wǎng)絡(luò)服務(wù)器
                                java -cp derby.jar;derbynet.jar org.apache.derby.drda.NetworkServerControl shutdown                                

在客戶端,需要安裝:

  • db2jcc.jardb2jcc_license_c.jar,用于 JDBC 驅(qū)動程序。
  • inventory.jar,這個 jar 包含了應(yīng)用程序的各個類。通過使用 eclipse 導(dǎo)出功能,可以很容易地基于應(yīng)用程序包創(chuàng)建這個 JAR。

 

這些組件可以復(fù)制到任何裝有 JVM 的機(jī)器上。當(dāng)網(wǎng)絡(luò)服務(wù)器正在運(yùn)行時,可以使用以下命令啟動應(yīng)用程序:


清單 15. 啟動客戶機(jī)應(yīng)用程序
                                java -cp db2jcc.jar;db2jcc_license_c.jar;inventory.jar bookstoreapp.clientside.Inventory                                

下圖闡明了網(wǎng)絡(luò)服務(wù)器配置中應(yīng)用程序的部署:


圖 11. 網(wǎng)絡(luò)服務(wù)器部署配置

下圖展示了應(yīng)用程序在生產(chǎn)環(huán)境中的執(zhí)行:


圖 12. 已部署的網(wǎng)絡(luò)服務(wù)器的執(zhí)行


圖 13. 已部署的客戶機(jī)應(yīng)用程序的執(zhí)行

嵌入式服務(wù)器配置

網(wǎng)絡(luò)服務(wù)器配置也許最適合這種類型的應(yīng)用程序,但是也可以使用嵌入式服務(wù)器配置,比如出于性能方面的原因。

在部署應(yīng)用程序之前,需要在代碼中作一下修改,使連接指向嵌入式服務(wù)器,而不是遠(yuǎn)程服務(wù)器。這可以通過修改 JDBC 驅(qū)動程序類名和連接 URL 來實(shí)現(xiàn)這一點(diǎn):


清單 16. 新的連接代碼
                                Class.forName("org.apachy.derby.jdbc.EmbeddedDriver");                                String url = "jdbc:derby:bookstoredb";                                

完成這些修改之后,便可以使用 Eclipse 導(dǎo)出功能將應(yīng)用程序的類打包到 JAR 文件中,并將下列文件部署到生產(chǎn)機(jī)器上:

  • derby.jar,其中包含 Derby 數(shù)據(jù)庫引擎和 JDBC 驅(qū)動程序。
  • inventory.jar,其中包含應(yīng)用程序的類。
  • bookstoredb/ 目錄,其中包含數(shù)據(jù)庫,還包括帶有存儲過程和函數(shù)的 JAR 文件。

 

可以使用下列命令啟動應(yīng)用程序:


清單 17. 啟動應(yīng)用程序
                                java -cp derby.jar;inventory.jar  bookstoreapp.clientside.Inventory                                

下圖闡明了應(yīng)用程序在嵌入式服務(wù)器配置中的部署:


圖 14. 嵌入式服務(wù)器部署配置
 

遷移到 DB2

雖然 Apache Derby 是一種非常健壯的、可伸縮的數(shù)據(jù)庫,但是由于以下原因,您有理由轉(zhuǎn)而使用企業(yè)數(shù)據(jù)庫,例如 DB2 UDB:

  • 功能缺乏。
  • 性能受限。
  • 需要與其他數(shù)據(jù)庫集成。

 

由于有了 DB2 plug-ins for Eclipse,并且客戶機(jī)應(yīng)用程序是基于標(biāo)準(zhǔn) JDBC 接口的,所以從 Derby 到 DB2 的遷移很容易完成。

遷移數(shù)據(jù)庫

第一步是遷移數(shù)據(jù)庫本身。DB2 plug-ins for Eclipse 提供了一個工具來自動地將 Apache Derby 數(shù)據(jù)庫遷移到 DB2 for Linux、Unix 和 Windows。

首先通過在 DB2 CLP 中發(fā)出 create database bookstoredb 命令創(chuàng)建一個 DB2 數(shù)據(jù)庫。

然后可以通過在 Database Explorer 視圖中右擊之前創(chuàng)建的 derby 數(shù)據(jù)庫條目并選擇 ‘Migrate to DB2 UDB…’ 動作來調(diào)用遷移工具。確保 DB2 服務(wù)器已經(jīng)啟動,并遵循使用說明來創(chuàng)建 DB2 數(shù)據(jù)庫、遷移數(shù)據(jù)庫對象和遷移實(shí)際數(shù)據(jù)。


圖 15. 使用 DB2 plug-ins for Eclipse 遷移 Derby 數(shù)據(jù)庫

手動遷移不受支持的對象

完成了數(shù)據(jù)庫的遷移之后,遷移工具會給出一個報(bào)告,指出遷移獲得成功,但是有些對象不能遷移。當(dāng)前版本的遷移工具不支持觸發(fā)器和函數(shù),因此需要手動遷移這些對象。

Apache Derby SQL 語言是與 DB2 兼容的語言,因此可以重復(fù)使用以前的 SQL 語句來創(chuàng)建丟失的對象。在 Database Explorer 中右擊 DB2 連接,并打開一個新的 SQL Scrapbook。

包含 Java 函數(shù)的 JAR 文件的安裝與 Derby 的安裝類似,惟一的區(qū)別是無需將 JAR 文件添加到類路徑。從 DB2 連接打開一個 SQL scrapbook,并輸入以下命令:


清單 18. 在 DB2 中安裝 JAR 文件
                                CALL sqlj.install_jar('functions.jar', 'bookstore.jar1', 0)                                

為了創(chuàng)建函數(shù)和觸發(fā)器,只需將之前使用的 SQL 語句復(fù)制和粘貼到 SQL scrapbook 中。記住,一次只能執(zhí)行一條語句,因而不能使用冒號作為結(jié)束符。


清單 19. 在 DB2 中創(chuàng)建函數(shù)和觸發(fā)器
                                create function bookstore.updateQuantity(id int, title varchar(128), author varchar(128),                                oldQuantity int, newQuantity int) returns int                                PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA                                EXTERNAL NAME 'bookstoreapp.StoredProcs.updateQuantity'                                create trigger bookstore.updateQuantityTrig after update of quantity on books                                referencing OLD as OLD NEW as NEW for each row mode db2sql                                VALUES(updateQuantity(NEW.id, NEW.title, NEW.author, OLD.quantity, NEW.quantity))                                

遷移客戶機(jī)應(yīng)用程序

遷移客戶機(jī)應(yīng)用程序的主要工作是修改建立數(shù)據(jù)庫連接的那部分代碼:

  • 既然不再使用 Derby,那么右擊 bookstore 項(xiàng)目并選擇“Apache Derby->Remove Apache Derby nature”。這將從構(gòu)建路徑中刪除 Derby JAR 文件。
  • 編輯項(xiàng)目的 Java 構(gòu)建路徑,并添加 DB2 JDBC 驅(qū)動程序 jar 文件:db2jcc.jar and db2jcc_license_cisuz.jar,對于 Windows 機(jī)器,這兩個文件通常可以在 C:\Program Files\IBM\SQLLIB\java\ 目錄下找到。
  • 在 Java 代碼中,將 JDBC 驅(qū)動程序的類名更改為 com.ibm.db2.jcc.DB2Driver
  • 再將連接 URL 更改為:jdbc:db2://localhost:50000/BOOKSTORE,并更改用戶名和密碼。
  • 由于可能沒有 bookstore 用戶名,因此需要更改 DB2 默認(rèn)模式。這可以通過在客戶機(jī)應(yīng)用程序初始化時發(fā)出以下命令來完成:stmt.execute("SET CURRENT SCHEMA = bookstore");

 

雖然 JDBC API 允許以相同的方式連接到任何數(shù)據(jù)庫,但發(fā)送到數(shù)據(jù)庫的實(shí)際的 SQL 查詢必須遵從數(shù)據(jù)庫 SQL 語言。因此,遷移 JDBC 應(yīng)用程序時需要重新編寫某些 SQL 查詢。在這個例子中,Derby 語言是 DB2 語言的一個子集,因此不存在這方面的問題,您無需對 SQL 查詢作任何修改。

現(xiàn)在應(yīng)用程序應(yīng)該可以進(jìn)行編譯,并且可以成功地在 DB2 數(shù)據(jù)庫上運(yùn)行。還可以像在 Derby 網(wǎng)絡(luò)服務(wù)器配置中那樣部署應(yīng)用程序。

結(jié)束語

在閱讀本文之后,您應(yīng)該能夠有效地使用為 Derby 提供的基于 Eclipse 的不同工具開發(fā) Apache Derby 應(yīng)用程序。您還應(yīng)該可以執(zhí)行一些相關(guān)的任務(wù),例如在各種可能的配置中部署這種應(yīng)用程序,或者將數(shù)據(jù)庫和應(yīng)用程序遷移到 DB2 UDB。

下載

描述 名字 大小 下載方法
Java source code for the Inventory application Inventory.java 2 KB HTTP

參考資料



關(guān)于作者

Gilles Roux 是 IBM DB2 組織中的一名信息管理軟件工程師。他的主要工作是開發(fā)數(shù)據(jù)庫遷移工具。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Cloudscape數(shù)據(jù)庫介紹及幾個問題
在Eclipse下,從安裝到使用Derby插件
用 Eclipse、WTP 和 Derby 構(gòu)建 Web 應(yīng)用程序
Derby 使用的2種方式:內(nèi)嵌和獨(dú)立
HIVE一些小技巧和java操作hive
Java SE 6 新特性: Java DB 和 JDBC 4.0
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服