idata數據訪問組件庫
下載:idata數據訪問組件庫 for RAD Studio RX10.2 使用 bin\dclidata250.bpl 安裝組件
idata 組件是基於 Indy10 開發的, 由服務端作爲中間層服務器,建立客戶端與後臺數據庫的通信。
idata是高效、安全、穩定的數據訪問組件,你可以構建自己的登錄認證系統,同時數據傳輸(SQL指令、參數、數據集)是經過壓縮與動態加密的。
idata是 RTL 組件,可應用於 Win32、Win64、Linux64、Android、OSX、iPad、iPhone 系統的 Delphi 與 C++Builder 開發。
類與組件表
場合 | idata | 名稱 | 說明 |
客 戶 端 | 類 | TIdField | 內存數據訪問類 |
TIdCustomDataSet | 數據集基類模型 | ||
組件 | TIdMemDataSet | 內存表組件 | |
TIdDBConnection | 數據庫連接器組件 | ||
TIdDBQuery | 數據訪問組件 | ||
服 務 端 | 類 | TIdDBPoolConnector | 池連接器類 |
TIdContextSession | 服務端會話類 | ||
組件 | TIdDBPoolController | 池控制器組件 | |
TIdDBPoolMethod | 池方法組件 | ||
TIdDBServer | 服務器組件 |
CSDN_ID: sczyq 聯繫QQ:79896009
TIdField
聲明:
TIdField = class;
TIdField 是內存數據訪問類。
屬性:
屬性 | 說明 |
DataSet: TIdCustomDataSet | 數據集類指針 |
Field: TField | 所關聯的 TField 類 |
DataType: TFieldType | 與 TField 的屬性相同 |
DataSize: Integer | |
IsNull[AIndex: Integer] : Boolean | 識別該記錄的值是否是 NULL |
AsBytes[AIndex: Integer] : TBytes | 將該記錄的值轉換爲相應的數據類型,顧名思義的,不適當的數據轉換可能會產生異常。 |
AsVariant[AIndex: Integer] : Variant | |
AsString[AIndex: Integer] : String | |
AsInteger[AIndex: Integer] : Longint | |
AsBoolean[AIndex: Integer] : Boolean | |
AsFloat[AIndex: Integer] : Double | |
AsCurrency[AIndex: Integer] : Currency | |
AsDateTime[AIndex: Integer] : TDateTime | |
AsLargeInt[AIndex: Integer] : Largeint | |
AsSQLTimeStamp[AIndex: Integer] : TSQLTimeStamp | |
AsLongWord[AIndex: Integer] : LongWord | |
AsExtended[AIndex: Integer] : Extended | |
AsSingle[AIndex: Integer] : Signle |
例如:採用 AsBytes 方法訪問 Blob 字段
Var LStream : TMemoryStream; LBytes : TBytes; begin LStream := TMemoryStream.Create; try // IdDataSet : TIdCustomDataSet LBytes := IdDataSet.IdFieldByName(‘Picture’).AsBytes[IdDataSet.DataIndex]; LStream.Write(LBytes, Length(LBytes)); // Image : TImage Image.Picture.Bitmap.LoadFromStream(LStream); finally LStream.Free; end; end; |
TIdCustomDataSet
聲明:
TIdCustomDataSet = class(TDataSet);
TIdCustomDataSet 是idata的數據集基類模型。
屬性:
DataCount: Integer
獲取內部數據總數, 與數據是否過濾 Filtered 無關,
例如: 總記錄100條, 過濾後是80條 | ||
Filtered | DataCount | RecordCount |
False | 100 | 100 |
True | 100 | 80 |
快速統計代碼比較:
常規寫法, 記錄訪問模式 |
function TForm1.GetSumValue : Currency; var LField : TField; OldRecNo : Integer; Begin Result := 0; // IdDataSet : TIdCustomDataSet LField := IdDataSet.FieldByName(‘Value’); OldRecNo := IdDataSet.RecNo; try IdDataSet.DisableControls; IdDataSet.First; while (not IdDataSet.Eof) do begin Result := Result + LField.AsCurrency; IdDataSet.Next; end; finally IdDataSet.RecNo := OldRecNo; IdDataSet.EnableControls; end; end; |
idata寫法, 內存數據訪問模式 |
function TForm1.GetSumValue : Currency; var I : Integer; LIdField : TIdField; Begin Result := 0; // LIdDataSet : TIdCustomDataSet LField := LIdDataSet.IdFieldByName(‘Value’);
// 常規寫法, 也是數據未過濾或者全部記錄統計 For I := 0 TO LIdDataSet.DataCount – 1 do Result := Result + LIdField.AsCurrency[I]; { // 如果記錄已經過濾, 只統計已經過濾後的, 就應該這樣寫 For I := 1 TO LIdDataSet.RecordCount do Result := Result + LIdField.AsCurrency[LIdDataSet.DataIndexOf(I)]; } end; |
DataIndex: Integer
獲取當前記錄的數據索引號
LookupOptions: TLookupOptions
使用Lookup 方法時使用的查找選項
ReadOnly: Boolean
數據集是否是隻讀的
Sort: String
進行數據記錄重排序, 允許多字段排序。
表達式格式: 字段名與關鍵字並且關鍵字之間用空格分開, 多個字段之間用分號。
關鍵字,與次序無關 | 說明 |
DESC | 倒序 |
CASE | 大小寫不敏感的, 僅適用於字符數據類型 |
例如: 將Price (價格)作爲從少到大排序,Name (名稱)倒序,並且大小寫不敏感。
Sort := ‘Price;Name DESC CASE’;
VirtualFieldDefs: TFieldDefs
始終存在的本地定義的 Field
如果VirtualFieldDefs 定義的 Field 名稱與 SQL查詢結果的字段有重名,則數據類型由SQL查詢決定。
例:
VirtualFieldDefs 定義 | ||
Name | DataType | Size |
NO | ftAutoInc |
|
TEXT | ftString | 32 |
SQL字段名與VirtualFieldDefs字段名不重疊的結果 | |||
SQL 查詢 | SELECT Id, Name, Value FROM TABLE_1 | ||
Name | DataType | Size | 說明 |
Id | ftInteger |
| 類型來自於 TABLE_1 |
Name | ftWideString | 40 | |
Value | ftCurrency |
| |
NO | ftAutoInc |
| 類型來自於 VirtualFieldDefs 定義 |
TEXT | ftString | 32 |
SQL字段名與VirtualFieldDefs字段名有重疊的結果 | |||
SQL 查詢 | SELECT Id AS No, Name, Value FROM TABLE_1 | ||
Name | DataType | Size | 說明 |
No | ftInteger |
| 類型來自於 TABLE_1 |
Name | ftWideString | 40 | |
Value | ftCurrency |
| |
TEXT | ftString | 32 | 類型來自 VirtualFieldDefs |
即使 LocalEditor = False ,由 VirtualFieldDefs 定義而產生的字段,數據修改後,總是不會提交到遠程服務器。
VirtualFieldDefs 的 Field 類型屬性定義。
ftAutoInc: 初始數據的序號,從1開始,只增不減,即使是中間插入。
數值型:初始數據是0
字符型:初始數據是空
Blob 類型:初始數據是NULL
VirtualFieldDefs 定義使數據集操作更加靈活, 程序操作更加方便。
方法:
function IdFieldOf(const AField: TField) : TIdField;
根據字段類獲取 TIdField 類
參數 | 說明 |
AField | 字段類指針 |
function IdFieldByName(const AFieldName: String) : TIdField;
根據字段名獲取 TIdField 類
參數 | 說明 |
AFieldName | 字段名 |
function DataIndexOf(ARecNo : Integer) : Integer;
將記錄號轉換爲數據索引號
參數 | 說明 |
ARecNo | 記錄號 |
function FindDataIndex(const KeyFields: String;
const KeyValues: Variant;
Options: TLocateOptions = []) : Integer;
查找符合條件的首條數據所在的記錄, 返回數據索引號
參數 | 說明 | |
KeyFields | 字段名列表 | 參照 Locate 方法 |
KeyValues | 值列表 | |
Options | 查找選項 |
function FindRecNo(const KeyFields: String;
const KeyValues: Variant;
Options: TLocateOptions = []): Integer;
查找符合條件的首條數據所在的記錄, 返回記錄號
參數 | 說明 | |
KeyFields | 字段名列表 | 參照 Locate 方法 |
KeyValues | 值列表 | |
Options | 查找選項 |
procedure SaveToStream(AStream: TStream;
AExcludeVirtual : Boolean = False);
保存數據到idata數據格式流, 與記錄是否過濾相關
參數 | 說明 |
AStream | 目標流,必須已經初始化 |
AExcludeVirtual | 是否排除由VirtualFieldDefs 產生的字段 |
procedure SaveToFile(AFileName: String;
AExcludeVirtual : Boolean = False);
保存數據到idata數據格式文件, 與記錄是否過濾相關
參數 | 說明 |
AFileName | 文件名,建議包括完成路徑 |
AExcludeVirtual | 是否排除由VirtualFieldDefs 產生的字段 |
事件:
OnFilterData : TIdFilterDataEvent 記錄過濾器事件
與 OnFilterRecord 過濾器事件作用相同,但OnFilterRecord 事件優先,只有不存在OnFilterRecord 事件的情況下,纔會使用OnFilterData 事件。
但是,OnFilterRecord 事件是記錄型的,DataSet在執行過濾時,需要移動記錄號。而OnFilterData 是內存數據型的,執行過濾時,不會移動記錄號,因此具有更高的效率。
OnFilterRecord 與 OnFilterData的代碼比較:
OnFilterRecord 記錄訪問過濾模式 |
procrdure TForm1.IdDBQuery1FieldRecord(DataSet: TDataSet; var Accept: Boolean); begin // 執行到這裏時,DataSet 會移動記錄號,你以當前記錄訪問數據 Accept := IdDBQuery1.FieldByName(‘Value’).AsCurrency > 100; end; |
OnFilterData 內存數據訪問過濾模式 |
procrdure TForm1.IdDBQuery1FieldData(DataSet: TDataSet; const Index : Integer; var Accept: Boolean); begin // 執行到這裏時,DataSet 不會移動記錄號,使用Index去訪問數據 Accept := IdDBQuery1.IdFieldByName(‘Value’). AsCurrency[Index] > 100; end; |
討論: 爲什麼內存數據訪問會比記錄訪問效率更高?
內存數據訪問, 是直接從內存中提取數據, 原理是: DATA -> VALUE
記錄訪問, 是間接的通過緩存提取數據, 原理是:DATA -> BUFFER -> VALUE 即:每一次移動記錄, 都會將當前內存記錄複製到緩存區, 然後再從緩存中提取值,而且DataSet每一次移動記錄(即使DisableControls), 都需要執行一批相應的指令,因而影響了效率。
TIdMemDataSet
聲明:
TIdMemDataSet = class(TIdCustomDataSet);
TIdMemDataSet 是內存表組件。
方法:
procedure CreateDataSet;
創建由VirtualFieldDefs 定義的字段並且打開空數據集
procedure CreateFieldsFromDataSet(ADataSet: TDataSet);
創建由源數據集相同的字段並且打開空數據集,如果存在VirtualFieldDefs 定義的字段並且字段名稱未重疊,能夠一併創建。源數據集的記錄不會複製過來。
參數 | 說明 |
ADataSet | 源數據集 |
procedure AddRecordsFromDataSet(ADataSet: TDataSet);
追加源數據集的記錄到當前數據集,字段名或數據類型不相同的數據會被拋棄,使用該方法前,數據集必須是活動的。
參數 | 說明 |
ADataSet | 源數據集 |
procedure LoadFromDataSet(ADataSet: TDataSet);
裝載源數據集的數據到當前數據集,該方法的作用就是執行 CreateFieldsFromDataSet和 AddRecordsFromDataSet。
參數 | 說明 |
ADataSet | 源數據集 |
procedure LoadFromStream(AStream: TStream);
從idata數據格式流中裝載數據到當前數據集,如果存在VirtualFieldDefs 定義的字段並且字段名稱未重疊,能夠一併創建。
參數 | 說明 |
AStream | 目標流,是使用 SaveToStream 導出的 |
procedure LoadFromFile(AFileName: String);
從idata數據格式文件中裝載數據到當前數據集, 如果存在VirtualFieldDefs 定義的字段並且字段名稱未重疊,能夠一併創建。
參數 | 說明 |
AFileName | idata數據格式文件名,建議使用完整路徑 |
procedure EmptyDataSet; 清空數據。
TIdDBConnection
聲明:
TIdCustomDBConnection = class(TCustomConnection);
TIdDBConnection = class(TIdCustomDBConnection);
TIdCustomDBConnection 是idata的數據庫通訊類模型。
TIdDBConnection 是idata的數據庫通訊組件。
屬性:
Host : String
服務器的主機地址,可以是域名。
Port : TIdPort
服務器的端口號,默認是698。
IPVersion
連接服務器採用的IP協議,默認是IPv4。
ReuseSocket
服務器是否重用連接。
Username : String
登錄服務器的用戶名,是否需要決定於服務器。
Password : String
登錄服務器的口令,是否需要決定於服務器。
BlockSize : Word
數據通信的每個塊最少值,單位是KB,默認值是512KB,該值在大數據量的情況下,起作用。
值 | 響應速度 | 通信次數 |
變大 | 劣 | 優 |
變小 | 優 | 劣 |
CommandTimeout : Word
命令執行超時等待時間,單位是秒,當向服務器發送SQL指令後,如果超過這個等待時間無響應,視爲超時,並拋出異常(有些情況是實際是執行成功了的, 只是執行時間過長而已)。
ConnectionTimeout : Word
連接服務器的超時等待時間,單位是秒,當準備向服務器連接後,如果超過這個等待時間無響應,視爲超時,並拋出異常。
Identity : Largeint
服務器與客戶端通信的唯一的連接碼,每次連接服務器都會分配一個不同的連接碼,該屬性是隻讀的。
DBProduct : String
服務器端後臺數據庫產品名稱,客戶獲取該數據庫產品名稱的作用,主要是用於客戶端開發時編寫SQL語句時,可以根據該屬性編碼不同的SQL指令。
事件:
OnLock : TNotifyEvent
當鎖定Socket時發生該事件,一般情況下是在開始執行SQL前。
OnUnlock : TNotifyEvent
當解鎖Socket時發生該事件,一般情況下是執行SQL並已經完成後。
TIdDBMakeUserInfo = procedure (const AParams : TParams);
OnMakeUserInfo : TIdDBMakeUserInfo
連接服務器時發生該事件。需要提供哪些參數由服務器決定,如果沒有編寫相應的事件,系統會自動加入 Username 與 Password 到這個參數列表。
參數 | 說明 |
AParams | 客戶端登錄參數表 |
TIdDBSQLAction = (saOpen, saAppend, saUpdate, saDelete, saExecute);
TIdDBSQLExceptionEvent = procedure (Sender: TObject; SQL : TStrings;
const Action : TIdDBSQLAction; E: Exception);
OnSQLException : TIdDBSQLExceptionEvent
當SQL發生異常時發生該事件。
參數 | 說明 |
Sender | 產生異常的組件類 |
SQL | SQL 語句列表 |
Action | 當前的動作 |
E | 異常類 |
OnConnected : TNotifyEvent
當連接成功時發生該事件。
OnDisconnected : TNotifyEvent
當斷開連接時發生該事件。
方法:
procedure Lock; 鎖定 Socket
procedure Unlock; 解鎖 Socket。
鎖定與解鎖是配套的,建議使用 try … finally … end 處理機制。
try Lock; … finally Unlock end; |
在使用TIdDBQuery執行SQL指令或時,能夠自動鎖定與解鎖,你無需編寫這些鎖定與解鎖的代碼Socket。只有在使用Socket執行擴展的協議時,才需要用到Lock 和 Unlock。
Procedure QueryToStream(AStream : TStream, ASQL : String ASQL);
執行查詢SQL指令,將結果輸出到流。
參數 | 說明 |
AStream | 目標流,指針必須初始化 |
ASQL | SQL指令 |
Procedure QueryToStream(AStream : TStream; ASQL : TStrings ASQL, AParams : AParams = nil);
執行查詢SQL指令,將結果輸出到流。
參數 | 說明 |
AStream | 目標流,指針必須初始化 |
ASQL | 多行SQL指令表 |
AParams | 與SQL指令表對應的參數,無參數可省略 |
function ExecuteSQL(ASQL : String) : Integer;
執行SQL指令,返回少於0則表示失敗的。執行時自動加鎖與解鎖Socket。
參數 | 說明 |
ASQL | SQL指令 |
function ExecuteSQL(ASQL : TStrings; AParams: TParams = nil) : Integer;
執行SQL指令,返回少於0則表示失敗的。執行時自動加鎖與解鎖Socket。
參數 | 說明 |
AStrings | 多行SQL指令表 |
AParams | 與SQL指令表對應的參數,無參數可省略 |
function BeginTrans : Integer; 啓動事務, 啓動前自動鎖定Socket。
function CommitTrans : Boolean; 提交事務,執行成功自動解鎖Socket。
function RollbackTrans : Boolean; 回滾事務,執行成功自動解鎖Socket。
建議使用 try … exception … end 異常處理。
try BeginTrans; … CommitTrans; exception RollbackTrans; end; |
TIdDBQuery
聲明:
TIdDBQuery = class(TIdCustomDataSet);
TIdDBQuery 是SQL數據訪問組件。
屬性:
property Connection : TIdCustomDBConnection
遠程數據連接器。
property SQL : TStrings
SQL指令。
property Params : TParams
SQL指令內包含的參數列表。
property LocalEditor : Boolean
決定數據編輯器是否是本地的。這個值必須是數據集在關閉的狀態時才能改變。
如果這個值爲 True,那麼,這個 TIdDBQuery 就是一個內存表,數據編輯後不會提交到SQL服務器。
如是果這個值爲 False(默認),那麼,當發生數據編輯提交,記錄刪除等操作, 同步提交到SQL服務器,並且必須成功, 否則產生異常。
方法:
procedure OpenSQL(ASQL : String);
打開由參數指令決定的數據。
參數 | 說明 |
ASQL | SQL指令 |
這個方法只是簡化了代碼編寫, 與Open 不同點在於,Open 方法必須先定義屬性SQL指令,然後才能Open。
如果存在VirtualFieldDefs 定義的字段並且字段名稱與SQL返回結果未重疊,能夠一併創建, 具體內容請見 TIdCustomDataSet 的屬性VirtualFieldDefs 說明。
function ExecSQL(ASQL : String = ‘’); : Integer;
執行SQL。
參數 | 說明 |
ASQL | SQL指令,如果空指令由執行屬性SQL定義的指令 |
這個方法也是簡化了代碼編寫,但如果參數存在SQL指令,則不會改變屬性SQL的定義。
事件:
property OnFetchProgress : TDataSetNotifyEvent
當SQL連接器獲取到一個數據塊,並處理完該數據塊時產生該事件,SQL獲取數據可能由多個數據塊組成。得到該事件表示SQL正在處理。
property OnFetchComplete : TDataSetNotifyEvent
當SQL獲取並處理完全部數據塊時產生該事件,得到該事件表示SQL已經完成。
TIdDBPoolConnector
聲明:
TIdDBPoolConnector = class(TComponent);
池連接器類,你要通過控制器方法獲取並回收,而不是創建與刪除。
屬性:
property Controller : TIdDBPoolController;
池控制器。
property Connection : TCustomConnection;
源數據庫連接,來自池初始化方法 DoInitialize。
property DataSet : TDataSet;
數據集,一般是Query組件,來自池初始化方法 DoInitialize。
property SQL : TStrings;
SQL指令。
property Params : TParams;
SQL指令內包含的參數列表。
property Activity : TDataTime
當前連接器最後活動的時間。
方法:
procedure Clear;
清空SQL指令與參數, 並關閉DataSet數據集。
procedure CloseSQL;
關閉數據集, 如何做決定於池方法 DoCloseSQL。
procedure OpenSQL;
打開由參數指令決定的數據, 如何做決定於池方法 DoOpenSQL。
procedure ExecSQL;
執行由參數指令決定的數據, 如何做決定於池方法 DoExecSQL。
procedure BeginTrans;
啓動一個數據庫事務, 如何做決定於池方法 DoBeginTrans。
procedure CommitTrans;
提交當前數據庫事務, 如何做決定於池方法 DoCommitTrans。
procedure RollbackTrans;
回滾當前數據庫事務, 如何做決定於池方法 DoRollbackTrans。
TIdContextSession
聲明:
TIdContextSession = class(TIdServerContext);
服務器會話類與協議庫。你無需創建該類,在一些服務器事件中會用到這個類。
屬性:
Connector : TIdDBPoolConnector;
源數據庫連接池連接器。
Identity : Largeint;
當前會話種子。
Username : String;
用戶名。
BlockSize : Word;
數據傳送塊大少,參照 TIdDBConnection.BlockSize 屬性。
LoginTime : TDateTime;
登錄時間。
property Activity : TDataTime
當前連接最後活動的時間。
TIdDBPoolMethod
聲明:
TIdCustomDBPoolMethod = class(TComponent)
TIdDBPoolMethod = class(TIdCustomDBPoolMethod)
源數據庫連接池控制器方法。編寫這些事件過程,決定於你採用哪種源數據庫連接方式(BDE/ADO/FireDAC/更多)。
事件:
TDBConnectorInitialize = procedure(AOwner : TComponent;
var AConnection : TCustomConnection; var ADataSet : TDataSet) of object;
OnInitialize: TDBConnectorInitialize;
初始化池連接器組件事件,你必須創建池連接器的 AConnection 與 ADataSet 組件。
參數 | 說明 |
AOwner | 創建池連接器組件的屬主 |
AConnection | 源數據庫連接組件 |
ADataSet | 數據集的指針 |
OnCloseSQL: TDBConnectorMetdod;
關閉數據集時啓動該事件。
OnOpenSQL: TDBConnectorMetdod;
打開SQL指令時啓動該事件。
OnExecSQL: TDBConnectorMetdod;
執行SQL指令時啓動該事件。
OnBeginTrans: TDBConnectorMetdod;
開始一個數據庫事務時啓動該事件。
OnCommitTrans: TDBConnectorMetdod;
提交當前數據庫事務時啓動該事件。
OnRollbackTrans: TDBConnectorMetdod;
回滾當前數據庫事務時啓動該事件。
討論:
你也可以通過繼承TIdCustomDBPoolMethod 的類來提供給池控制器,而不採用TIdDBPoolMethod 組件方法。
例如:採用 ADO 方式連接源數據庫的方法類 ADOPoolMethod.pas
unit ADOPoolMethod;
{ 本代碼配合數據庫連接池組件使用, 僅適用於 ADO 環境 使用本代碼後, 你就無需再編寫 TDBPoolMethod 的事件處理過程. 只需要將這個 Pas 加入到你的工程, 然後創建該TADODBPoolMethod類給控制器 IdDBPoolController1.PoolMethod := TADODBPoolMethod.Create(Self, ConnStr); 由於 ADO 是 Windows 的 COM 組件, 而連接池初始化是在線程中完成的 所以你必須編寫 TDBPoolController 組件的 OnBeforeRun 與 OnAfterRun 事件方法 進行 COM 的初始化與回收 procedure TMyServer.IdDBPoolController1BeforeRun(ASender : TObject); begin CoInitialize(nil); end; procedure TMyServer.IdDBPoolController1AfterRun(ASender : TObject); begin CoUninitialize(); end; }
interface
uses System.Classes, Data.DB, idata.Pool, Data.Win.ADODB;
type TADODBPoolMethod = class(TIdCustomDBPoolMethod) private FConnectionString : String; function GetQuery(AConnector : TIdDBPoolConnector) : TADOQuery; protected procedure DoInitialize(AConnector : TIdDBPoolConnector; var AConnection : TCustomConnection; var ADataSet : TDataSet); override; procedure DoCloseSQL(AConnector : TIdDBPoolConnector); override; procedure DoOpenSQL(AConnector : TIdDBPoolConnector); override; procedure DoExecSQL(AConnector : TIdDBPoolConnector); override; procedure DoBeginTrans(AConnector : TIdDBPoolConnector); override; procedure DoCommitTrans(AConnector : TIdDBPoolConnector); override; procedure DoRollbackTrans(AConnector : TIdDBPoolConnector); override; public constructor Create(AOwner : TComponent; AConnectionString : String); reintrodce; end;
implementation
constructor TADODBPoolMethod.Create(AOwner : TComponent; AConnectionString : String); begin inherited Create(AOwner); FConnectionString := AConnectionString; end;
function DODBPoolMethod.GetQuery(AConnector : TIdDBPoolConnector) : TADOQuery; var I : Integer; LParam : TParam; LParameter : TParameter; begin Result := TADOQuery(AConnector.DataSet); Result.Close; Result.SQL.Clear; Result.SQL.Assign(AConnector.SQL); for I := 0 to AConnector.Params.Count - 1 do begin LParam := AConnector.Params[I];
LParameter := Result.Parameters.FindParam(LParam.Name); if not Assigned(LParameter) then LParameter := Result.Parameters.AddParameter;
LParameter.Assign(LParam); end; end;
procedure TADODBPoolMethod.DoInitialize(AConnector : TIdDBPoolConnector; var AConnection : TCustomConnection; var ADataSet : TDataSet); begin AConnection := TADOConnection.Create(AConnector); TADOConnection(AConnection).ConnectionString := FConnectionString; AConnection.LoginPrompt := False;
ADataSet := TADOQuery.Create(AConnector); TADOQuery(ADataSet).Connection := TADOConnection(AConnection); end;
procedure TADODBPoolMethod.DoCloseSQL(AConnector : TIdDBPoolConnector); var LQuery : TADOQuery; begin LQuery := TADOQuery(AConnector.DataSet); LQuery.Close; LQuery.SQL.Clear; end;
procedure TADODBPoolMethod.DoOpenSQL(AConnector : TIdDBPoolConnector); begin GetQuery(AConnector).Open; end;
procedure TADODBPoolMethod.DoExecSQL(AConnector : TIdDBPoolConnector); begin GetQuery(AConnector).ExecSQL; end;
procedure TADODBPoolMethod.DoBeginTrans(AConnector : TIdDBPoolConnector); begin TADOConnection(AConnector.Connection).BeginTrans; end;
procedure TADODBPoolMethod.DoCommitTrans(AConnector : TIdDBPoolConnector); begin TADOConnection(AConnector.Connection).CommitTrans; end;
procedure TADODBPoolMethod.DoRollbackTrans(AConnector : TIdDBPoolConnector); begin TADOConnection(AConnector.Connection).RollbackTrans; end;
end. |
TIdDBPoolController
聲明:
TIdDBPoolController= class(TComponent);
源數據庫連接池控制器。
屬性:
Active : Boolean;
池控制器是否在開啓狀態。
PoolCount : Integer;
當前池連接器計數。
AlwaysCount : Word;
始終保持連接器的數量。
IdlenessTimeout : Word;
當某個連接器空閒了這個時間(秒)後,並且連接器總數多於始終保持數時自動釋放掉。
PoolMethod : TIdCustomDBPoolMethod;
連接器方法。
方法:
function Acquire(ASession : TObject) : TIdDBPoolConnector;
獲取一個連接器。
procedure Recovery(AConnector : TIdDBPoolConnector);
回收一個連接器。
事件:
AfterRun : TNotifyEvent;
完成後事件,適用於Windows 系統釋放線程COM。
BeforeRun : TNotifyEvent;
啓動時的事件,適用於Windows 系統初始化線程COM。
OnPoolChanged : TNotifyEvent;
連接器的數量改變時啓動該事件。
OnSQLException : TDBSQLExceptionEvent;
當SQL發生異常時發生該事件。
TIdDBServer
聲明:
TIdCustomDBServer = class(TIdCustomTCPServer);
TIdDBServer = class(TIdCustomDBServer);
數據庫服務器組件。
其他由 Indy10 的 TIdCustomTCPServer 提供的屬性、方法、事件不再列出。
屬性:
PrimaryKeys : TStrings;
表主鍵字段列表。行格式是 “表名=字段;”多個字段用分號分隔。
DBController : TIdDBPoolController;
源數據庫連接池控制器。
DBProduct : String;
源數據庫產品標識, 參照 TIdDBConnection.DBProduct 屬性。
LoginTimeout : Word;
客戶端登錄超時設置(秒)。
TransactionTimeout: Word;
事務超時設置(秒)。
InactiveTimeout: Word;
客戶端會話超時設置(秒),某個連接在這個時間內無會話的即被判定爲超時並斷開這個他。
事件:
OnAfterRun : TNotifyEvent;
完成後事件,適用於Windows 系統釋放線程COM。
OnBeforeRun : TNotifyEvent;
啓動時的事件,適用於Windows 系統初始化線程COM。
TIdDBLoginVerifyMethod = procedure(ASession : TIdContextSession;
AParams : TParams; var AStatus: Boolean) of object;;
OnLoginVerify : TIdDBLoginVerifyMethod;
客戶端登錄時使用該事件,該事件內定義了客戶端登錄所需提供的參數,根據這些參數判定登錄是否成功。
參數 | 說明 |
ASession | 客戶端會話類,你可以通過這個類去獲取池連接器 |
AParams | 客戶端提供的登錄參數表 |
AStatus | 返回值,登錄成功時置爲 True |
如果沒有寫該事件過程,登錄總是成功的(匿名的)。
該事件決定了客戶端登錄事件的編寫方式, 參見 TIdDBConnection.OnMakeUserInfo 事件說明。
OnExtendProtocol : TIdDBExtendProtocolMethod;
服務端擴展協議,當客戶端發送了無法識別的協議時,觸發該事件,目前是保留的。
TIdDBGetPrimaryKeyMethod = procedure(ASession : TIdContextSession;
const ATableName : String; var AFieldNames : String) of object;
OnGetPrimaryKey : TIdDBGetPrimaryKeyMethod;
獲取表主鍵字段的事件。不同的數據庫產品獲取表主鍵的方式不相同,主鍵主要應用在TIdDBQuery 數據提交時使用。
參數 | 說明 |
ASession | 客戶端會話類,你可以通過這個類去獲取池連接器 |
ATableName | 表名 |
AFieldNames | 返回字段列表,每個字段後加上半角分號 |