zoukankan      html  css  js  c++  java
  • ThreeTierDatenbankanwendung mit ADO

    Three-Tier-Datenbankanwendung mit ADO

    Frage: Wie kann ich eine Three-Tier-Datenbankanwendung, die mit ADO auf die Datenbank zugreift, ohne TClientDataset umsetzen?

    Antwort: Das folgende Beispiel für eine Three-Tier-Datenbankanwendung nutzt COM+ auf der Server-Seite, um ein mit Daten gefülltes Recordset-Objekt (ADO) an den Client zurückzuliefern (Interface-Methode GetRS) beziehungsweise dessen Änderungen wieder in der Datenbank einzuarbeiten (Interface-Methode UpdRS).

    Implementierung im COM+ Objekt (Server)

    Das COM+-Objekt erzeugt das mit den Datensätzen der Ergebnismenge der SELECT-Abfrage gefüllte Recordset, und liefert dieses über den Interface-Zeiger _Recordset an den Client zurück. Damit das Recordset diesen Transport "überlebt", muss vorher die Datenbankverbindung zwischen Recordset und Datenbank gekappt werden (Methode Set_ActiveConnection). In der Gegenrichtung sorgt der Server dafür, dass das vom Client als Interface-Zeiger übergebene Recordset mit den vom Anwender geänderten Daten vor dem Aufruf der Methode UpdateBatch kurzzeitig wieder mit der Datenbank verbunden wird. Da ADO über die Fähigkeiten von OLE DB automatisch einen Datenbankverbindungs-Pool nutzt, führt dieses ständige Verbinden und Trennen zu keiner Verzögerung, da sofort eine freie Datenbankverbindung aus dem Pool zugeordnet wird und der Pool zur Laufzeit dynamisch wächst, wenn es notwendig wird.

    unit UpdBatch_Impl;
    { SYMBOL_PLATFORM OFF}
    
    interface
    uses ActiveX, Mtsobj, Mtx, ComObj, UpdBatch_Impl_TLB, StdVcl, ADODB_TLB;
    type TUpdBatchObj = class(TMtsAutoObject, IUpdBatchObj) protected procedure UpdRS(const aRS: _Recordset; out sSrvMsg: WideString); safecall; procedure GetRS(out aRS: _Recordset; out sSrvMsg: WideString); safecall; { Protected-Deklarationen } end;
    implementation
    uses ComServ, Variants;
    resourcestring cCS = 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;' + 'Initial Catalog=tempdb;Data Source=(local)';
    procedure TUpdBatchObj.GetRS(out aRS: _Recordset; out sSrvMsg: WideString); var aCon : _Connection; aRSTmp: _Recordset; begin aCon := CoConnection.Create as _Connection; aCon.CursorLocation := adUseClient; aCon.Open(cCS, '', '', adConnectUnspecified); try aRSTmp := CoRecordSet.Create as _Recordset; aRSTmp.CursorLocation := adUseClient; aRSTmp.Open('select PK, Wert1, Wert2 from UpdateBatchNOTNULL', aCon, adOpenStatic, adLockBatchOptimistic, adCmdText); aRS := aRSTmp; aRS._Set_ActiveConnection(nil); finally aCon.Close; end; sSrvMsg := 'ok'; SetComplete; end;
    procedure TUpdBatchObj.UpdRS(const aRS: _Recordset; out sSrvMsg: WideString); var aCon : _Connection; begin aCon := CoConnection.Create as _Connection; aCon.CursorLocation := adUseClient; aCon.Open(cCS, '', '', adConnectUnspecified); aRS.Set_ActiveConnection(aCon); aRS.UpdateBatch(adAffectAll); aRS._Set_ActiveConnection(nil); aCon.Close; aCon := nil; sSrvMsg := 'ok'; SetComplete; end;
    initialization TAutoObjectFactory.Create(ComServer, TUpdBatchObj, Class_UpdBatchObj, ciMultiInstance, tmApartment); end.
    Implementierung im Client

    Der Client hat keine Verbindung zur Datenbank, er kennt noch nicht einmal die Datenbank, von der die Daten stammen. Statt dessen erhält der Client vom COM+-Objekt des Servers nur das bereits mit den Datensätzen der Ergebnismenge gefüllte Recordset, um dieses einer TADODataSet-Komponente unterzuschieben. Diese TADODataSet-Komponente wird im Objektinspektor nicht konfiguriert, sondern die Komponeten übernimmt die Daten direkt vom bereits gefüllten Recordset-Objekt. TADODataSet dient nur dazu, über TDataSource ein TDBGrid zur Bearbeitung der Datenmenge nutzen zu können. Um die vom Anwender vorgenommenen Änderungen an den Datensätzen in die Datenbank einzuspielen, ruft der Client die Interface-Methode UpdRS des COM+-Objekts auf, um dabei das gefüllte Recordset in Form des Interface-Zeigers als Parameter zu übergeben. Zusätzlich kann der Client festlegen, dass dabei nur die vom Anwender geänderten Datensätze zum Server transportiert werden sollen.
    unit CltUpdateBatchFrm;
    
    interface
    uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB, ExtCtrls, DBCtrls, Grids, DBGrids, StdCtrls, UpdBatch_Impl_TLB, ComCtrls;
    type TForm1 = class(TForm) Button1: TButton; DBGrid1: TDBGrid; DBNavigator1: TDBNavigator; ADODataSet1: TADODataSet; DataSource1: TDataSource; StatusBar1: TStatusBar; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } FSrv : IUpdBatchObj; public { Public-Deklarationen } end;
    var Form1: TForm1;
    implementation
    { *.dfm}
    uses ADODB_TLB, ADOInt;
    procedure TForm1.FormCreate(Sender: TObject); begin FSrv := CoUpdBatchObj.CreateRemote('192.168.10.1'); end;
    procedure TForm1.Button1Click(Sender: TObject); var aRS : ADODB_TLB._Recordset; swSrvMsg : WideString; begin FSrv.GetRS(aRS, swSrvMsg); ADODataSet1.Recordset := ADOInt._Recordset(aRS); ADODataSet1.Active := True; StatusBar1.SimpleText := swSrvMsg; end;
    procedure TForm1.Button2Click(Sender: TObject); var aRS : ADODB_TLB._Recordset; swSrvMsg : WideString; begin aRS := ADODB_TLB._Recordset(ADODataSet1.Recordset); FSrv.UpdRS(aRs, swSrvMsg); StatusBar1.SimpleText := swSrvMsg; end;
    procedure TForm1.ADODataSet1NewRecord(DataSet: TDataSet); begin ADODataSet1.FieldByName('Wert2').Value := ''; end;
    end.
    Die ganzen Hintergründe dazu sind in den folgenden Büchern zu finden:
    a) http://www.software-support.biz/sus/sus_buch/psecom,id,4,nodeid,11,_language,de.html
    b) http://www.software-support.biz/sus/sus_buch/psecom,id,21,nodeid,11,_language,de.html


  • 相关阅读:
    Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.
    Introduction to the Standard Directory Layout
    import 原理 及 导入 自定义、第三方 包
    403 'Forbidden'
    https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
    These interactions can be expressed as complicated, large scale graphs. Mining data requires a distributed data processing engine
    mysqldump --flush-logs
    mysql dump 参数
    mysql dump 参数
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
  • 原文地址:https://www.cnblogs.com/fuyingke/p/254659.html
Copyright © 2011-2022 走看看