程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 開發基於 DB2 Everyplace 產品的快遞解決方案

開發基於 DB2 Everyplace 產品的快遞解決方案

編輯:DB2教程

解決方案簡介

本文將介紹一個基於 IBM DB2 Everyplace 產品的快遞解決方案。在本章中,我們將通過介紹解決方案的應用場景和 DB2 Everyplace 的知識背景,進而給出這個解決方案的架構設計和流程實現。

場景介紹

在一個快遞公司日常工作中,郵遞人員是工作的主體,他們奔波於客戶和公司之間,進行包裹的收取或者分發工作。但是他們常常會面臨這樣的問題:郵遞人員在處理包裹的過程中,由於傳統的信息交換方式往往不能使他們高效地與客戶或者與快遞公司之間進行信息的交換,從而使得他們無法迅速地獲取客戶的需求或者得到公司的工作安排指示。雖然傳統的通訊方式比如打電話可以進行部分的工作安排和協調工作,但是由於缺乏一個統一的信息管理平台,不同郵遞人員之間也無法進行有效地協調,使得整體的工作效率低下。

快遞公司希望能有一個先進的信息系統幫助他們管理和協調日常工作,使得郵遞人員能夠及時得到自己的工作任務,並將自己的工作情況及時地更新到這個系統。而且在整體工作的協調上,能根據各個郵遞人員實時的具體狀況,比如當前位置、是否空閒等信息來合理安排新的工作,從而帶來整體工作效率的提高,減少人力成本,並減少客戶的等待服務時間,提高客戶的滿意度,創造新的商業價值。

IBM 公司基於 DB2 Everyplace 移動數據庫中間件產品對此場景提出了一個優秀的解決方案原型,我們稱為 Mobile Parcel Demo。在後面的章節中將對此解決方案的實現思路和方法作具體的介紹,以此使讀者了解 DB2 Everyplace 產品,並掌握基於此產品的解決方案開發過程。

知識背景

DB2 Everyplace 作為 IBM 普適計算解決方案的一部分,將企業數據服務從後端的業務數據庫擴展到前端的手持設備,使得前端與後端的數據進行無縫連接,從而滿足了電子商務移動化的需要。(見圖 1)

DB2 Everyplace 基於三層架構,由下面三部分組成:

DB2 Everyplace 移動設備端(Mobile Devices):包括移動數據庫和同步客戶端。DB2 Everyplace 移動數據庫允許不同的手持設備上的數據可以存放在數據庫中進行管理。DB2 Everyplace 同步客戶端運行於手持設備端負責移動數據庫與同步服務器進行同步。

DB2 Everyplace 同步服務器(Sync Server):作為企業數據源與手持設備移動數據庫之間的橋梁,DB2 Everyplace 同步服務器運行於服務器端,並負責管理業務數據庫與手持設備上的移動數據庫進行雙向的數據同步。同步服務器還負責鏡像數據庫和企業後台源數據庫的復制。

DB2 Everyplace 後台源數據庫(Data Source):DB2 Everyplace 支持多個業界著名的數據庫,包括 DB2,Oracle,Microsoft SQL Server 和 Informix。

圖 1. DB2 Everyplace 產品的結構模型

開發基於 DB2 Everyplace 產品的快遞解決方案

解決方案架構設計

我們在上一節中已經介紹了 DB2 Everyplace 是如何在客戶端和服務器端進行數據同步的。解決方案的設計也是基於這樣一種客戶端 - 服務器(C-S)的架構模式。我們用圖 2 來表示 DB2 Everyplace 是如何應用到這個具體的場景中的:

圖 2. 解決方案應用場景流程圖

開發基於 DB2 Everyplace 產品的快遞解決方案

由圖 2 我們可以看到解決方案的具體流程。在此場景中,一共有三類主體:客戶(Customer)、快遞公司前台(Front Desk)和快遞公司郵遞員(Operator),其中郵遞員是客戶端的操作主體,而前台是服務器端的操作主體。具體的工作流程分為兩類,分別為郵件的獲取 (Parcel Pickup) 和郵件的分發 (Parcel Delivery)。

客戶如果想要投遞一個自己的郵件,則要向快遞公司前台發起一個投遞請求(Pickup Request),要求郵遞員上門取包裹。前台(服務器端)根據請求與客戶設定一個預約(Appointment),並將相關信息,如預約的客戶信息、時間信息等存入公司的源數據庫 (DB2 Source Database),源數據庫與鏡像數據庫進行復制,並通過 DB2 Everyplace 同步服務器與郵遞員手中的移動設備進行數據同步。移動設備上安裝有解決方案的客戶端應用程序,對數據進行相關處理之後,郵遞員就可以得到自己的取件任務信息,並在指定的時間赴約,獲取客戶要投遞的包裹。交易完成之後,通過客戶端應用程序將交易的信息如收據等存入自己設備上的 DB2 Everyplace 數據庫,之後可以通過移動設備與服務器端的數據同步,將相關信息提交到快遞公司的前台。這樣郵遞員就完成了一次郵包的獲取任務。

類似地,當快遞公司收到某郵包需要讓郵遞員投遞給相關客戶的時候,前台將與客戶設定一個投遞預約,郵遞員將根據此預約在指定的時間把郵件投遞給這位客戶。

可以看到,在整個場景流程中,郵遞員只需要通過移動設備與公司前台數據庫進行同步(Synchronize)就可以獲取自己的任務,並將任務完成信息反饋,整個過程快捷高效。

搭建開發環境

Mobile Parcel Demo 是一個 C-S 架構的應用程序。在本章中,我們從客戶端和服務器端分別介紹所用到的開發工具以及開發環境的搭建。

客戶端開發環境

客戶端應用程序采用 WinCE 平台上的 J2ME 開發,使用的開發工具為 WebSphere Studio Device Developer(WSDD)。WSDD 是 IBM Workplace ClIEnt Technology,Micro Edition 平台的一個主要集成組件,它是一個基於 Eclipse 的集成開發環境,用於創建和測試可以部署到手機和其它嵌入式設備上的應用程序。

下面介紹在 WSDD 上搭建一個 J2ME 開發環境的過程。

打開 WSDD,新建一個項目(見圖 3)。

圖 3. 創建 WSDD 項目

開發基於 DB2 Everyplace 產品的快遞解決方案

選擇項目類型,點擊“下一步”(見圖 4)。

圖 4. 選擇 J2ME 作為項目類型

開發基於 DB2 Everyplace 產品的快遞解決方案

填寫項目名稱,點擊“下一步”(見圖 5)。

圖 5. 填寫項目名稱

開發基於 DB2 Everyplace 產品的快遞解決方案

選擇類庫:JCL Foundation 1.0,點擊“完成”(見圖 6)。這樣,一個新的 J2ME 項目就成功建立起來了,可以在 src 文件夾下添加 Java 文件以編寫我們的客戶端應用程序。

圖 6. 選擇類庫

開發基於 DB2 Everyplace 產品的快遞解決方案

為了使我們編寫的程序能部署到移動設備上,必須配置應用程序的運行環境,包括配置構建版本等操作。點擊菜單中的“運行”->“運行…”項,見圖 7,彈出運行環境配置面板。

圖 7. 配置構建版本

開發基於 DB2 Everyplace 產品的快遞解決方案

見圖 8,在“運行”面板中新建一個啟動配置。

圖 8. 新建啟動配置

開發基於 DB2 Everyplace 產品的快遞解決方案

配置這個啟動配置,包括:在“Java 應用程序”選項卡中配置“項目”、“設備或 JRE”、“Java 應用程序”三條配置信息。見圖 9,其中將“項目”輸入欄中的信息與我們所創建的 J2ME 項目相關聯;在“設備或 JRE”中配置 J9 虛擬機與我們要將應用程序安裝到移動設備的具體路徑;在“Java 應用程序”中添加並配置我們所需的通用構建器以生成 JAR 文件到移動設備。

圖 9. 配置啟動配置

開發基於 DB2 Everyplace 產品的快遞解決方案

在“自變量”選項卡中配置所需的程序自變量和 VM 自變量。一般來說程序自變量不用填寫,而在 VM 自變量中需指明應用程序在移動設備上引用的 Java 虛擬機(比如 J9)和外部庫的路徑(見圖 10)。

圖 10. 配置環境變量

開發基於 DB2 Everyplace 產品的快遞解決方案

其他配置選項卡一般為默認值即可。在 WSDD 中編寫完成應用程序之後,確保已經有移動設備連接到本地工作站上,在“運行”選項卡中點擊“運行”按鈕,即可將客戶端應用程序按照配置部署到移動設備上了。

服務器端開發環境

服務端應用程序采用 Rational Software Development Platform (RSDP) 開發環境。RSDP 是 IBM Rational 軟件開發平台,它基於 Eclipse 技術,將各種不同的開發技術融合於一個平台。它提供了 Java/J2EE/Web Service、UML、C++ 等技術的統一開發環境,並使得開發和測試都變得簡單和可控制。

我們的服務器端應用程序主要使用 JSP 進行開發。搭建開發環境的過程並不復雜,首先創建一個企業應用程序(此應用程序最後將被導出為 EAR 包部署在 WebSphere Application Server 上),見圖 11,在左側“項目資源管理器”面板中右鍵點擊“企業應用程序”文件夾,並選擇新建 ->企業應用程序項目。

圖 11. 創建企業應用程序項目

開發基於 DB2 Everyplace 產品的快遞解決方案

在彈出的對話框中輸入“db2e_mparcel”作為項目名稱,點擊“完成”。

我們需要創建一個動態 Web 項目作為企業應用程序項目的子模塊,這個動態 Web 項目是真正實現服務器端功能的 JSP 頁面集合。見圖 12,在左側的“項目資源管理器”面板中右鍵點擊“動態 Web 項目”,並選擇新建 ->動態 Web 項目。

圖 12. 創建 Web 項目

開發基於 DB2 Everyplace 產品的快遞解決方案

在彈出的對話框中輸入“mparcel”作為項目名稱,並點擊“完成”來創建這個 Web 項目。

在這個例子中,我們在 Web 項目下的“Java Resources”文件夾中編寫我們的 Java Beans 和 Java Class,在“WebContent”中編寫 JSP 頁面。在“部署描述符”中編寫 Servlet 和相關的部署配置信息。

在動態 Web 項目“mparcel”中編寫我們的代碼後,我們可以通過右鍵點擊 JSP 文件,並選擇運行 ->在服務器上運行來將我們的 Web 項目部署到 RSDP 中內置的 WebSphere Application Server 上,浏覽其頁面效果,也可以通過選擇“調試”菜單來調試我們的項目。

建立了動態 Web 項目之後,我們需要將這個項目與之前建立的企業應用程序相關聯。見圖 13,在我們建立的企業應用程序“db2e_mparcel”下的“模塊”文件夾上右鍵 ->導入 ->WAR 文件,在彈出的面板中的“Web 項目”輸入框中用下拉框選擇我們建立的動態 Web 項目“mparcel”並點擊“完成”,就將 Web 項目包含進企業應用程序。

圖 13. 關聯項目

開發基於 DB2 Everyplace 產品的快遞解決方案

類似的,我們還可以在“項目實用程序 JAR”和“實用程序 JAR”中關聯這個企業應用程序所需的項目和其他 JAR。這樣,服務器端的開發環境就搭建完成了。

解決方案應用程序開發

本章將詳細介紹客戶端和服務器端的應用程序的具體開發過程,包括使用的具體技術、關鍵功能的實現方式以及部分代碼樣例。

客戶端應用程序開發

Mobile Parcel Demo 的客戶端是一個基於 J2ME 的應用程序,采用經典的 MVC 三層結構。Model 層使用 JDBC 與 DB2 Everyplace 數據庫連接;使用 ESWT 作為 VIEw 層;DB2 Everyplace 的關鍵功能和特征,比如數據的同步等在 Controller 層實現。下面分別介紹。

客戶端應用程序的數據庫是 DB2 Everyplace,首先我們要編寫代碼來完成與數據庫的連接以及數據訪問。DB2 Everyplace 數據庫的表和其內容是通過與企業數據庫比如 DB2 同步 (Synchronize) 得到的。在同步之後,應用程序將通過 JDBC 與數據庫表相連接,並使用 SQL 語句進行相應的操作。在編寫連接程序之前,需要先將 db2ejdbc.jar 和 isync4j.jar 以及 jdbc.jar 這 3 個 jar 包引入我們的 WSDD 項目 ParcelClIEnt 下,並在 WSDD 運行面板中配置相應的類路徑(見客戶端開發環境一節)。見清單 1,整個數據庫連接過程與在非移動平台數據庫 JDBC 連接類似。

清單 1.DB2E 數據庫連接和封裝

public class DB {
private static DB instance = null;
private Connection con;
// 構造函數
private DB() {
try {
DB2eDataSource ds = new DB2eDataSource();
ds.setUrl("jdbc:db2e:/parcelclIEnt/data");// 設置索要連接的 db2e 數據庫路徑  
con = ds.getConnection();// 獲得連接
con.setAutoCommit(false);
}
// 處理異常 , 省略
catch (SQLException sqlEx) {  
......
}      
}
      
// 單鍵方法用來返回 DB 唯一實例
public static synchronized DB getInstance() {
if (instance == null) {
instance = new DB();
}
return instance;
}
}

我們再來看看客戶端的界面實現。客戶端程序的界面部分采用 eSWT 編寫,SWT(Standard Widget Toolkit)是一個開源的 GUI 編程框架,而 eSWT 作為 SWT 的一個子集,是在嵌入式編程中的一個 GUI 庫。首先我們要在項目中引入 eswt-converged.jar 包,才能在程序中使用這個 GUI 框架。

我們將介紹一個使用 eSWT 編寫的簡單表單界面過程。要在界面上繪制圖像或者控件的一般過程如下:首先,創建一個界面外殼 Shell,並獲取相關的顯示信息和設置格式,然後在這個 Shell 上創建一系列的控件,並設置他們的響應函數(Listener),最後使用 FormLayout 來設置這些控件的位置信息。在完成了 Shell 上所有控件的繪制之後,需要重載一個 Shell.open() 函數,來打開這個界面。清單 2 的代碼簡單展示了這個過程。

清單 2. eSWT 創建用戶界面

public class MainShell {
private Shell shell;
public MainShell(final Display display) {
shell = new Shell(display, SWT.RESIZE | SWT.CLOSE); // 創建 shell 實例
FormLayout layout = new FormLayout();// 設置界面整體信息
layout.marginWidth = 100;
layout.marginHeight = 100;
shell.setLayout(layout);
shell.setText("Parcel_Main");
// 創建一個 button 控件
Button sync = new Button(shell, SWT.PUSH);
sync.setText("Sync");
sync.addListener(SWT.Selection, new Listener() { // 設置響應函數
public void handleEvent(Event event) {
goSync();
}
});
// 設置 Layout 位置信息
FormData syncLayout = new FormData();
syncLayout.left = new FormAttachment(40, 0);
syncLayout.right = new FormAttachment(80, 0);
syncLayout.height = 40;
syncLayout.bottom = new FormAttachment(100,0);
sync.setLayoutData(syncLayout);
}
// 重載 open 方法
public void open() {
shell.open();
}
}

客戶端應用程序提供可視化界面,使得郵遞員可以方便地對包裹進行收取和分發,以及對相關工作例如包裹信息的查詢,客戶端和服務器端的同步等。圖 14 是客戶端程序的邏輯結構。

圖 14. 客戶端用戶邏輯和界面結構

開發基於 DB2 Everyplace 產品的快遞解決方案

讀者可以通過將這個結構流程與之前提到的應用場景做比較來更好地了解客戶端部分的邏輯。

最後,我們來看看客戶端的中間邏輯層的實現。客戶端邏輯的關鍵功能是通過調用 DB2 Everyplace 提供的 API 來實現的,有關 API 的具體說明請參見參考資源中的 DB2 Everyplace Application and Development Guide。在這裡我們舉一個例子,介紹客戶端與服務器端數據庫同步實現的具體方法。DB2 Everyplace v912 開始支持 XML 類型和 BLOB 類型的同步。

同步的過程大致是這樣的:

首先,在連接 Sync Server 之前需要設置相關的連接信息,比如驅動信息,Server 的 URL,連接的用戶名、密碼等信息。我們使用一個 property 文件來保存這個信息,在 sync 初始化的時候讀進這個文件,並將相關信息設置完畢。這個 property 文件可以通過客戶端的一個頁面進行修改。

然後,通過讀取 Sync Driver 並從 Sync Manager 獲取 Sync Service 的一個實例創建一個同步服務,並設置一個此服務的事件處理函數 Sync Listener 來處理相關的同步信息(通過實現接口 ISyncListener 中的方法 eventIssued),完成數據的同步。

此過程的主要代碼片斷見清單 3。

清單 3. Synchronize 的實現過程

public class ParcelSync implements ISyncListener{
// 設置一些 Sync 主體和變量
private ISyncProvider provider;
private ISyncService service;
private ISyncConfigStore config;
private ISyncDriver syncer;
//Implement eventIssued 方法處理相關 Sync 事件
public int eventIssued(ISyncEvent evt){
// 各類事件的處理
switch(evtType) {
case ISync.EVTTYPE_INFO:
case ISync.EVTTYPE_ERROR:
// 返回
return ISync.RTNCB_DONE;
// 其他 case,以下省略
……
default:
break;
}
return ISync.RTNCB_DEFAULT;
}
public void goSync(String propFile){
try {
int rc = 0;
// 讀取 property 文件
readPropertIEs(propFile);
// 加載 sync driver
Class.forName(userProps.getProperty("syncdriver"));
// 獲取 synchronization service 實例
provider =
ISyncManager.getISyncProvider(userProps.getProperty("syncprotocol"));
service =
provider.createSyncService(userProps.getProperty("server.url"), userProps);
// 獲取 configuration store 實例
config = service.getConfigStore(userProps.getProperty("path"));
// 獲取 sync driver 實例以運行 synchronization
syncer = config.getSyncDriver();
// 設置 listener
syncer.setSyncListener(this);
// 同步每個 subscription sets, 省略具體枚舉過程
rc = syncer.sync();
ssArr = config.getSubscriptionSets();
……
}
catch(ISyncException IE){
System.out.println("Exception code:" + IE.getCode());
IE.printStackTrace();
}
} //goSync
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved