不知道在三层中大家可否碰到过这种问题:由于客户端是多窗口,所以可能多个ClientDataSet对应服务器端的同一个Provider,不知大家如何解决。我使用了无状态Provider,但是在设计期没办法提取数据字段定义。
解决方案 »
- 关于动态报表的问题
- Indy的安装,安装出错,是何道理,快来顶啊
- 在线求助!!!哪个大哥,大姐有关于ABC控件的资料介绍,给我一份好么,谢谢了!
- 如何连接到oracle?
- 如何实现鼠标的跟随效果?
- 我加了一个DBMEMO,DBMEMO里显示的内容很多,可是DBMEMO里没有滚动条,可以加滚动条吗?谢谢!
- 函数的返回值要求是一个类,该怎么做?谢谢
- 关于C/S结构下的listview控件?
- 是否有dbctrlgrid 增强型控件?若可以请
- delphi5安装DELPHI4的控件时报错:INTERNAL ERROR:URW3010 什么意思?如何解决?
- 数据库连接问题,提示错误,请高手分析!
- 请问:delphi中如何用接口实现......
最简单的方法,设计多个Provider,然后动态切换.
| 服务器端 | |
|------------------------------|
| --------- --------- |
| |Provider1| |Provider2| |
| ---|----- ---|----- |
| | | |
-------|--------------|-------
----------|--------------|--------------------------------------------------------
| | 客户端 | |
|----------|--------------|--------------------------------------------------------|
| | | |
| ------|--------------|---------------- |
| |窗体一|实例1 \ | |
| |------|---------------\---------------| |
| | --|----------- -\------------ | |
| | |ClientDataSet1| |ClientDataSet2| | |
| | -------------- -------------- | |
| | | |
| -------------------------------------- |
| --------------|-----------|----------- |
| |窗体一实例2 | | | |
| |--------------|-----------|-----------| |
| | ----------|--- ----|--------- | |
| | |ClientDataSet1| |ClientDataSet2| | |
| | -------------- -------------- | |
| | | |
| -------------------------------------- |
----------------------------------------------------------------------------------
我的一些信息:
调试环境:ORACLE9I+DELPHI+其他平台
操作方法:在ORACLE中测试语句,然后写配置表<用来存储需要的字段信息>,ClientDataSet1中使用,另用配置表的信息完成对字段信息的提供。ClientDataSet1使用的是离线数据。
只有在OPEN/UPDATE的时候才有激活Provider1
下载到了本地,这样会导致网络洪流,可能淹没服务器。
用多字段定位,但主要是字段信息的提供.
自己的意见。由于上次没有考虑到篇幅宽度,所以使问题描述图发送后乱码,重排
后如下:
----------------------------
| 服务器端 |
|----------------------------|
| --------- --------- |
| |Provider1| |Provider2| |
| ---|----- ---|----- |
-----|-----------|----------
| |--------------------------------
|-----------|--------------------------- |
-----|-----------|----------------------- | |
| | 客户端 | | | |
|-----|-----------|-----------------------| | |
| | | | | |
| ---|-----------|------------------ | | |
| | |窗体一实例1 \ | | | |
| |---|-------------\----------------| | | |
| | -|------------ \-------------- | | | |
| | |ClientDataSet1| |ClientDataSet2|| | | |
| | -------------- -------------- | | | |
| | | | | |
| ---------------------------------- | | |
| | | |
| -----------------------------------+--- |
| | -----------------------+--------
| ---|-----------|------------------ |
| | |窗体一实例1 \ | |
| |---|-------------\----------------| |
| | -|------------ \-------------- | |
| | |ClientDataSet1| |ClientDataSet2|| |
| | -------------- -------------- | |
| | | |
| ---------------------------------- |
-----------------------------------------
只要在程序里动态的实现TClientDataSet的连接与释放,应该没有什么问题。不过如果多次打开关闭数据集,会使程序速度太慢。
报表设计,中文字段名翻译.我现在使用了数据运行期无状态绑定,解决了设计期字段定义这个问题,
同时由于Provider的无状态,可以使数据集共享,但客户端需要保留自己的状态.
i25ffz(Martin) 说得对。三层不能和两层的C/S结构那样设计
更为灵活, 比如资源的有效利用,提供良好的仲裁机制,再借助轻量级的数据访问机制:dbExpress
使得三层比C/S的运行效率以及资源利用率都有飞跃.其实分离及对象化使得设计条理更为清晰,
安全性更好,但很少人考虑到其中对象间的资源共享,客户间资源的共享,其实也就是缺乏一种
Pooling机制.
| 数据访问机制| | |
| -------- -+------------+- 无状态 |
|| | | | 业务对象A | | 业务对象|
|| | | | | | Pooling |
|| | -+------------+- |
|| 无状态 | | | |
||数据访问| -+------------+- |
||组件集合| | | 业务对象B | | |
|| | | | | | |
|| | | -+------------+- |
| ---+---- | | |
| | -+------------+- |
| | | | 业务对象C | | |
| | | | | | |
| | -+------------+- |
| | | | |
| | -+------------+- |
| | | | 业务对象D | | |
| | | | | | |
| | -+------------+- |
| ---+------- | | |
|| 公共 || -----------
|| 数据连接 ||
| ----------- |
-------------
{-------------------------------------------------------------------------------
过程名: TMaterialServer.OpenData
作者: 李文凯
日期: 2004.12.06
描述: 请修改
实现方法: 请修改
参数: SQLFlag: Integer; const SQLWhere: WideString; var Data: OleVariant
返回值: 无
-------------------------------------------------------------------------------}
function TMaterialServer.OpenData(SQLFlag: Integer;
const SQLWhere: WideString; var Data: OleVariant;
var strMSG: WideString): Integer;
var
strSQL: string;
strLog:string;
begin
strLog:='OpenData(SQLFLAG='+inttostr(SQLFlag)+',SQLWHERE='+SQLWHERE+')';
Result:=1;
strSQL:=getSQLByID(SQLFlag);
if strSQL='' then
begin
strMSG:='编号为['+IntToStr(SQLFlag)+']的SQL语句没有定义!与请系统管理员联系!';
MainServer.AddInformat(FUserNO,FUserName,'读数据',strMSG,strLog,1);
Exit;
end;
if Trim(SQLWhere)<>'' then strSQL:=Format(strSQL,[SQLWhere]);
try
dataset.Close;
dataset.EnableBCD:=False;
dataset.CommandText:=strSQL;
dataset.Open;
Data:=DSPRead.Data;
dataset.Close;
Result:=0;
except
On E:Exception do
begin
strMSG:='获得数据失败,与请系统管理员联系!';
MainServer.AddInformat(FUserNO,FUserName,'读数据','编号['+IntToStr(SQLFlag)+'] 读取出错'+E.Message,strLog,1);
end;
end;
cds.ProviderName:='';
end;
dataset: TADODataSet;
DSPRead: TDataSetProvider;
我就用一个!
TDataSetProvider本身就是一个无状态的,你的代码也只是增加了数据访问的安全性(过滤非法SQL
调用),我的做法是改造TDataSetProvider和TCliettDataSet.
是无状态的.
APage: Integer; var ATotalPage: Integer; var Data: OleVariant;
var MSG: WideString): Integer; safecall;分页读取
也是可以实现的!
服务器上是有访问就自己创建的,不明白,怎么会重复呢?顶一下。
所以可能多个ClientDataSet对应服务器端的同一个Provider每个clientdataset在对数据操作的时候
在其BeforeApplyUpdates(Sender: TObject;
var OwnerData: OleVariant);
begin
OwnerData:='select * form tablename';
end;
惭愧得很,我现在有个项目的三层开发怎么跟大家讨论的都不太相同啊?大家把自己如何解决的也都说说啊,我们学习一下,呵呵
另外加个问题:就是关于客户端与服务器端通信双方死机的问题,比如说在客户端调用中间应用服务器接口函数期间(返回之前),将服务器端的网线断了,客户端就死掉了,这些问题我找遍了资料都得不到答案,在版上问了多次,但也都没结果,不知道各位大哥在三层的实现中是不是从来都不存在这个问题阿?小弟很郁闷,呵呵
请参考代码:
Program Files\Borland\Delphi7\Demos\Midas\SharedConn