这些资料我也看过,但我一些具体的东西,我还是不太理解!
例如我将应用服务器做成了一个EXE,在RemoutDataModule中放了一个Database1,Query1,Session1,datasetProvider1,设置好后,代码如下:
unit Unit11_52;
interface
uses
Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
DBClient, Project11_5_TLB, StdVcl, Provider, Db, DBTables, Variants;
type
TTest115Server = class(TRemoteDataModule, ITest115Server)
Session1: TSession;
AdHocQuery: TQuery;
Database1: TDatabase;
AdHocProvider: TDataSetProvider;
procedure RemoteDataModuleCreate(Sender: TObject);
procedure RemoteDataModuleDestroy(Sender: TObject);
procedure AdHocQueryAfterOpen(DataSet: TDataSet);
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
function GetDatabaseNames: OleVariant;
safecall;
procedure SetDatabaseName(const DBName, UserName, Password: WideString);
safecall;
public
{ Public declarations }
end;
implementation
uses Unit11_51;
{$R *.DFM}
class procedure TTest115Server.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;
function TTest115Server.GetDatabaseNames: OleVariant;
var
I: Integer;
DBNames: TStrings;
begin
// 创建一个字符串数组来存放BDE所有的数据库别名数据。
DBNames := TStringList.Create;
try
// 利用Session组件来获取目前BDE所有的数据库别名数据。
Session1.GetDatabaseNames(DBNames);
// 建立一个变量数组给函数返回变量Result。
Result := VarArrayCreate([0, DBNames.Count - 1], varOleStr);
// 最后再把数据库别名数据指定给此变量数组。
for I := 0 to DBNames.Count - 1do
Result := DBNames;
finally
DBNames.Free;
end;
end;
procedure TTest115Server.SetDatabaseName(const DBName, UserName,
Password: WideString);
begin
try
// 把前台传来的数据库别名、用户在线名称、用户在线密码
// 等三项数据指定给Tdatabase组件,并且运行连接的操作。
Database1.Close;
Database1.AliasName := DBName;
if (UserName<>'') and (Password<>'') then
begin
Database1.Params.Values['PASSWORD'] := Password;
Database1.Params.Values['USER NAME'] := UserName;
end;
Database1.Open;
except
// 如果连接时发生错误时,则产生一个exception给前台程序
// 前台程序将会利用到这个exception来判断是否要把输入在
// 线数据的窗口叫起来。
on E: EDBEngineErrordo
raise Exception.Create('Password Required') ;
end;
end;
procedure TTest115Server.RemoteDataModuleCreate(Sender: TObject);
begin
// 增加一位前台的在线者(调用Form1上的过程)
MainForm.UpdateClientCount(1);
end;
procedure TTest115Server.RemoteDataModuleDestroy(Sender: TObject);
begin
// 减少一位前台的在线者(调用Form1上的过程)
MainForm.UpdateClientCount(-1);
end;
procedure TTest115Server.AdHocQueryAfterOpen(DataSet: TDataSet);
begin
// 新打开一个TQuery查询(调用Form1上的过程)
MainForm.IncQueryCount;
end;
initialization
TComponentFactory.Create(ComServer, TTest115Server,
Class_Test115Server, ciMultiInstance, tmApartment);
end.
我客户端加了一个:
DCOMConnection1,ClientDataSet1,DataSource1,dbgrid,button1,
调用如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, StdCtrls, Grids, DBGrids, DBClient, MConnect, SConnect,
ObjBrkr;
type
TForm1 = class(TForm)
DCOMConnection1: TDCOMConnection;
ClientDataSet1: TClientDataSet;
DBGrid1: TDBGrid;
Button1: TButton;
DataSource1: TDataSource;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
DCOMConnection1.Connected:=true;
ClientDataSet1.CommandText:='select * from emp_info where rybh=1';
ClientDataSet1.Open;
end;
end.
我想问各位高手,这是三层结构吗?如果是,和C/S结构有什么区别,我不是一样要在客户端写SQL语句!也就是说业务逻辑不是一样放在了客户端?
还有,如果我在RemoutDataModule中不用BDE,而是放一个ADOConnection1,ADOQuery1,datasetProvider1为什么我客户端就报错呢,说是"Commandtext changes are not allowd",难道用这种方式我就用不了ADO了吗?