日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java delphi 三层_三层架构delphi+Java+Oracle模式的实现

發布時間:2023/12/15 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java delphi 三层_三层架构delphi+Java+Oracle模式的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【架構簡介】

*本架構以delphi作為客戶端,Java作為服務端,oracle作為后臺數據庫數據。其中delphi客戶端的封裝為了保持與原來的開發方式兼容都是基于TclientDataSet實現的;

*本架構選擇基于阻塞模式的Indy通信套件作為通信工具;以tcp/ip作為通信協議 ,直接以流的的形式與Java服務端進行交互;

*本架構的通信過程如下:

請求開始->打包壓縮請求數據->發送請求數據->delphi端阻塞等待->Java端多線程響應請求->解壓解包請求數據->處理請求->打包壓縮處理結果->發送處理結果->

delphi端停止阻塞接收處理結果->解壓解包處理結果->顯示結果

*本架構主要解決以下問題:

1.如何將Java從數據庫中讀出來的數據打包成TClientDataSet可以讀取的數據包;要解決這個問題就需要深入了解TclientDataSet的DataPackage的xml格式。

2.如何將新增-修改-刪除后的TClientDataSet數據通過Java保存到數據庫中;要解決這個問題就需要深入了解TclientDataSet的Delta屬性。

3.如何處理Oracle的大對象字段類型(clob或blob)。

4.delphi端如何調用Java端定義的對應的業務邏輯供。

5.Java端多用戶并發處理效率問題。

6.數據包的格式定義‘打包解包‘壓縮解壓’加密解密問題。

1.【TclientDataSet的DataPackage格式】

TclientDataSet的DataPackage格式一般如下:

-

-

-

-

2.【DataPackage的結構分析】

整個XML定義了一個DataPacket;DataPacket包括兩個部分:MetaData和RowData。MetaData包括Fields和Params,即包括數據字段定義和數據集參數。

RowData為具體記錄。 下面詳細分析數據字段定義的方法。

Field節點的定義主要包括:

1>attrname指FieldName

2>fieldtype指字段類型

3>width指需要寬度的字段類型的寬度或數字的有效位數;

4>decimals指小數點右邊的位數;

Oracle主要字段類型具體的對應信息如下表:

_____________________________________________________________________

OracleType?| fieldtype? ?| WIDHT?| SUBTYPE???? ?| DECIMALS?| READONLY

---------------------------------------------------------------------

Char??????????? ??| string????? ?|???? 1??????????? FixedChar

---------------------------------------------------------------------

Char(n)??????? ?| string???? ? |??? ?n??????????? FixedChar

---------------------------------------------------------------------

Varchar(n)?? ?| string?????? |???? ?n

---------------------------------------------------------------------

Varchar2(n)? | string?????? |??? ? n

---------------------------------------------------------------------

data????????????? | dateTime?|

---------------------------------------------------------------------

Number(s,p)?| fixed?????? ?|??? ? s?????????????????????????????????????? p

---------------------------------------------------------------------

Number(*,p)?| fixed????? ?|???? ?38???????????????????????????????????? p

----------------------------------------------------------------------

Number(s)? ? | fixed????? ?|?????? ?s

----------------------------------------------------------------------

Number??????? | fixed????? ?|????? ? 38

----------------------------------------------------------------------

int????????????????| fixed??????? |?????? 38

----------------------------------------------------------------------

Smallint???????| fixed?????? ?|??????? 38

----------------------------------------------------------------------

Dec(s,p)????? | fixed?????? ?|???????? s?????????????????????????????????????p

----------------------------------------------------------------------

Float??????????? | R8???????? ??|

----------------------------------------------------------------------

Real?????????????| R8????? ??? ?|

----------------------------------------------------------------------

其中用SubType屬性來幫助決定類型。表中沒有值的單元格,表示該屬性沒有用到。

并且DataPakage中如果想包含中文的話,記得要在第一句的中間加上encoding=”GB2312”,否則用數據庫相關控件讀出來的只會是亂碼。

記住位置很重要的。你必須寫成下面的形式:

如果寫成下面的也是不滿足形式良好的規范的:

3.【XML的轉義字符】

在XML語言中,用實體對特殊字符進行轉義.

如果在XML文檔中使用類似"

所以不應該像下面那樣書寫代碼:

if salary < 1000 then

為了避免出現這種情況,必須將字符"

if salary < 1000 then

下面是五個在XML文檔中預定義好的實體:

---------------------

<? | < | 小于號

---------------------

>? | > | 大于號

---------------------

&? | & | 和

---------------------

' | ' | 單引號

---------------------

" | " | 雙引號

---------------------

實體必須以符號"&"開頭,以符號";"結尾。

注意: 只有"

4.【Oracle的大對象字段類型(clob和blob)】

因為TclientDataSet不支持clob和blob等大對象字段類型,所以我們要使用別的方法來實現相應的讀寫操作;

5.【關于TClientDataSet的Delta屬性】

TClientDataSet.Delta屬性表示當前操作的ClientDataSet中記錄變化的信息

Delta信息可以用另外的ClientDataSet來顯示;如myCDS.Data := OrgCDS.Delta

TclientDataSe的UpdateStatus屬性反映當前記錄的更新狀態; 根據更新數據的情況其可能的值分別為:

1.新增一條記錄時,在Delta中會有一條記錄,標記為usInserted;

2.修改記錄時,在Delta中對于同一條記錄會產生且僅產生兩條記錄:第一條為原始記錄,標記為usUnmodified,第二條只有修改過的字段才有值,標記為usModified

3.刪除記錄時,在Delta中會產生一條記錄,標記為usDeleted;

根據以上Delta屬性就可以生成相應的更新SQL語句;

6.【數據包的格式定義】

6.1.數據包采用變長字符串的方式組織,一般由數據節點和分隔符及結束符組成。具體結構如下圖:

|? 數據節點? |分隔符 |? 數據節點? |分隔符 |? 數據節點? |分隔符 | ... |結束符 |

6.2.數據節點一般由數據長度和數據值組成。

6.3.當數據值的長度小于等于999時數據節點的組成如下圖:

|數據長度 |? 數據值? |分隔符 |數據長度 |? 數據值??? |分隔符 | ... |結束符 |

6.4.當數據值的長度大于999時數據節點的組成如下圖:

|003? |數據長度的長度 |? /? ?|數據長度 |? 數據值??? |分隔符 | ... |結束符 |

6.5數據包格式定義說明:

#數據長度為數據值長度的長度字符串;

#數據長度的長度為數據值長度的長度字符串的長度字符串;

#分隔符一般為冒號;當數據值的長度大于999時分隔符為"/";

7.【JAVA應用服務器】

應用服務器最重要的就是穩定,支持高效的多用戶并發處理;所以應用服務器應該是無狀態的;然后是易于部署的;

java天生就是用來編寫服務器的;成熟的j2ee企業級應用;豐富的開源思想;于是java就成了實現應用服務器的不二選擇;

JAVA應用服務器具體實現以下功能:

1>使用一個ServerSocket監聽Delphi客戶端發送請求的命令;

2>針對每個Delphi客戶端發送的請求開啟線程解析處理請求;通過JAVA端的多線程來達到高效處理多用戶并發的情況。

3>通過反射和command設計模式來分派Delphi端請求的相應的業務邏輯對象進行處理;

3>通過JDBC與Oracle數據庫交互;

其實只要數據到了java端,那么只要你愿意你可以選擇任意的中間件技術:weblogic,websphere,jboss等等作為應用服務器,

而盡想其提供的豐富的管理功能;

8.【接口規劃】

*************************************************************************************************************************

函數功能: 發送操作命令和數據到應用服務器

函數聲明: function StreamCommand(ASendText:WideString;ASendStream:TStream=nil):TStream;stdcall;external Communication;

參數說明: -------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

ASendText?????? 要發送的字節數據(一般應包括命令信息)

-------------------------------------------------------

ASendStream???? 要發送的內存流或文件流等數據(默認為nil)

-------------------------------------------------------

函數說明:正常返回字節流數據(可能返回空串);異常返回nil;此函數一般供DLL中的接口函數調用;

用例:Result:=StreamCommand('013SelectCommand:045SELECT * FROM CRM_CUSTOMER WHERE B_COMPANY=1 :');

這個語句的意思是發送一個查詢命令到AppServer,命令的內容為SELECT * FROM CRM_CUSTOMER WHERE B_COMPANY=1;

如果命令能正確執行,那么AppServer會把查詢的結果打包發送到客戶端,以字節流的形式返回.

**************************************************************************************************************************

函數功能: 查詢單個數據集

函數聲明: function SelectCommand(ACDS: TClientDataSet;const ASelectText: string):Boolean;stdcall;external Communication;

參數說明: -------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

ACDS?????????? 存放查詢結果集的TClientDataSet

-------------------------------------------------------

ASelectText???? 要發送的單條查詢語句

-------------------------------------------------------

函數說明: 成功返回[true](包括只有數據元的空數據集);失敗返回[false]

用例: Result:=SelectCommand(cdsTemp,'SELECT * FROM CRM_CUSTOMER');這個語句的意思是:

發送一個查詢語句到AppServer,如果命令能正確執行,那么AppServer會把查詢的結果集打包發送到客戶端事先創建好的cdsTemp中.

*************************************************************************************************************************************

函數功能:同時查詢多個數據集

函數聲明:function SelectCommands(ACDS:Array of TClientDataSet;const ASelectText: TStringList):Boolean;stdcall;external Communication;

參數說明:-------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

ACDS?????????? 存放查詢結果集的多個TClientDataSet列表

-------------------------------------------------------

ASelectText???? 要發送的多條查詢語句列表

-------------------------------------------------------

函數說明:成功返回[true](包括只有數據元的空數據集);失敗返回[false]

用例:

var

sSql:string;

sList:TStringList;

cdsTemp1,cdsTemp2,cdsTemp3:TClientDataSet;

begin

try

cdsTemp1:=TClientDataSet.Create(nil);

cdsTemp2:=TClientDataSet.Create(nil);

cdsTemp3:=TClientDataSet.Create(nil);

sList:=TStringList.Create;

try

sSql:='SELECT * FROM Table1';

sList.Add(sSql);

sSql:='SELECT * FROM Table2';

sList.Add(sSql);

sSql:='SELECT * FROM Table3';

sList.Add(sSql);

//把第一條查詢語句的結果集存放到cdsTemp1,把第二條查詢語句的結果集存放到cdsTemp2,依次類推存放順序

SelectCommands([cdsTemp1,cdsTemp2,cdsTemp3],sList);

finally

if Assigned(cdsTemp1) then FreeAndNil(cdsTemp1);

if Assigned(cdsTemp2) then FreeAndNil(cdsTemp2);

if Assigned(cdsTemp3) then FreeAndNil(cdsTemp3);

if Assigned(sList) then FreeAndNil(sList);

end;

except

end;

end;

**************************************************************************************************************************

函數功能: 發送一條或多條update or insert or delete類型的SQL語句到應用服務器執行

函數聲明: function ExecuteCommands(const AExecuteText: TStringList): integer;stdcall;external Communication;

參數說明: -------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

AExecuteText???? AppServer能解析的SQL語句

-------------------------------------------------------

函數說明: 正常返回0;異常返回非0;本函數主要供ApplyUpdates函數調用;

用例:

**************************************************************************************************************************

函數功能: 發送一條update or insert or delete類型的SQL語句到應用服務器執行

函數聲明: function ExecuteCommand(const ACommandText:WideString):integer; stdcall;external Communication;

參數說明: -------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

ACommandText???? 要執行的SQL語句

-------------------------------------------------------

函數說明: 正常返回0;異常返回非0;

用例:

**************************************************************************************************************************

函數功能: 根據數據集列表的修改信息自動生成相應的SQL語句

函數聲明: function CreateUpdates(const ATableNames: array of string ;ACDS:array of TClientDataSet;var sSqlList:string): Boolean;stdcall; external Communication;

參數說明: -------------------------------------------------------

參數名稱????????????????????? 描述

-------------------------------------------------------

ATableNames???? 數據集列表對應的表名列表

-------------------------------------------------------

ACDS??????????? 修改過的數據集列表

-------------------------------------------------------

sSqlList???????? 存放對應生成的SQL語句

-------------------------------------------------------

函數說明: 成功返回[true];失敗返回[false]

本函數根據數據集中的修改信息自動生成Insert,Update,Delete類型的多條SQL語句.

用例: 1>Result:=CreateStatement(['TableName1','TableName2','TableName3','TableName4'],[cds1,cds2,cds3,cds4]); 或者

2>Result:=CreateStatement(['TableName1'],[cds1]);

本用例會根據數據集列表中每個數據集的修改信息自動生成相應的SQL語句,這樣就完成了操作界面到SQL語句之間的直接映射.

**************************************************************************************************************************

函數功能: 更新多個數據集

函數聲明: function ApplyUpdates(const ATableNames: array of string ; ACDS:array of TClientDataSet): Boolean;stdcall; external Communication;

參數說明: -------------------------------------------------------

參數名稱?????????????? 描述

-------------------------------------------------------

ACDS?????????? 要更新的數據集列表

-------------------------------------------------------

ATableNames???? 要更新的表名列表

-------------------------------------------------------

函數說明: 成功返回[true];失敗返回[false]

表名列表與數據集列表應該一一對應

用例: Result:=ApplyUpdates(['TableName1','TableName2','TableName3','TableName4'],

[cds1,cds2,cds3,cds4]);

本用例會根據數據集列表中每個數據集的修改信息自動生成相應SQL語句,然后把所有的SQL語句一起發送到AppServer進行事務處理.

*****************************************************************************************************************

函數功能: 保存Oracle大對象字段類型(clob或blob)

函數聲明: function SaveBlob(SqlText:WideString;LobID:WideString;LobContent:TStream):integer;stdcall; external Communication;

參數說明: -------------------------------------------------------

參數名稱?????????????? 描述

-------------------------------------------------------

SqlText?????????? 保存前要執行的SQL語句

-------------------------------------------------------

LobID???????????? 包含Oracle大對象字段類型的記錄的ID

-------------------------------------------------------

LobContent??????? 要保存的Oracle大對象字段類型的內容

-------------------------------------------------------

函數說明: 成功返回[0];失敗返回[非0]

用例:

*****************************************************************************************************************

函數功能: 顯示Oracle大對象字段類型(clob或blob)

函數聲明: function SelectBlob(LobID:WideString):TStream;stdcall; external Communication;

參數說明: -------------------------------------------------------

參數名稱?????????????? 描述

-------------------------------------------------------

LobID???????? 包含Oracle大對象字段類型的記錄的ID

-------------------------------------------------------

函數說明: 成功返回Oracle大對象字段類型對應的流;失敗返回[nil];

用例:

9.【擴展功能】

1>客戶端數據緩存機制保證運行的高效性:客戶端可以緩存大量的客戶端數據,并提供了一定程度的離線操作功能;

這樣在提高戶交互效率的同時,減少網絡數據通訊量;還能降低服務器的負載。

2>客戶端自動更新機制:便于客戶端的部署和版本更新

3>權限管理:包括功能權限和數據權限;

4>客戶端采用模塊化(DLL)設計保證系統的可擴展性;

5>運行時自定義報表;

6>JAVA應用服務器可采用數據庫連接池來提高訪問效率;

總結

以上是生活随笔為你收集整理的java delphi 三层_三层架构delphi+Java+Oracle模式的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。