【架构简介】
架构以delphi作为客户端,Java作为服务端,oracle作为后台数据库数据。
其中delphi客户端的封装为了保持与原来的开发方式兼容都是基于TclientDataSet实现的;
delphi客户端通过Socket直接以流的的形式与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.数据包的格式定义,打包解包,压缩解压,加密解密等问题。
7.其他扩展功能。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应用服务器可采用数据库连接池来提高访问效率;
架构以delphi作为客户端,Java作为服务端,oracle作为后台数据库数据。
其中delphi客户端的封装为了保持与原来的开发方式兼容都是基于TclientDataSet实现的;
delphi客户端通过Socket直接以流的的形式与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.数据包的格式定义,打包解包,压缩解压,加密解密等问题。
7.其他扩展功能。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应用服务器可采用数据库连接池来提高访问效率;
http://blog.csdn.net/sz_haitao/archive/2009/09/10/4539228.aspx
1、xml的解包效率太低
2、号称通用的ws,其实还是有很多细节需要双方一致才行的