使用FireDAC的TFDManager和TFDConnection组件实现运行时动态数据库连接
以下是一个通用的数据库连接方案,使用FireDAC的TFDManager和TFDConnection组件实现运行时动态数据库连接。支持多种数据库类型,采用面向对象封装:
unit DatabaseManager;
interface
uses
System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option,
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Comp.Client,
FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, Data.DB,
FireDAC.Comp.DataSet;
type
TDatabaseType = (dtSQLite, dtMySQL, dtPostgreSQL, dtMSSQL, dtOracle);
TDatabaseManager = class
private
FConnection: TFDConnection;
FManager: TFDManager;
FDatabaseType: TDatabaseType;
FLastError: string;
procedure ValidateDriver;
function GetConnectionDefName: string;
function GetDriverName: string;
function BuildParams(Params: TStrings): string;
public
constructor Create;
destructor Destroy; override;
procedure ConfigureConnection(DatabaseType: TDatabaseType; Params: TStrings);
function Connect: Boolean;
procedure Disconnect;
function ExecSQL(const SQL: string; Params: TArray<TVarRec>): Integer;
function OpenQuery(const SQL: string; Params: TArray<TVarRec>): TFDQuery;
property LastError: string read FLastError;
end;
implementation
{ TDatabaseManager }
constructor TDatabaseManager.Create;
begin
FManager := TFDManager.Create(nil);
FConnection := TFDConnection.Create(nil);
FManager.SilentMode := True;
FManager.Active := True;
end;
destructor TDatabaseManager.Destroy;
begin
Disconnect;
FConnection.Free;
FManager.Free;
inherited;
end;
procedure TDatabaseManager.ConfigureConnection(DatabaseType: TDatabaseType; Params: TStrings);
begin
FDatabaseType := DatabaseType;
FManager.ConnectionDefs.Clear;
// 添加新的连接定义
FManager.AddConnectionDef(
GetConnectionDefName,
GetDriverName,
BuildParams(Params)
);
end;
function TDatabaseManager.Connect: Boolean;
begin
Result := False;
try
ValidateDriver;
FConnection.ConnectionDefName := GetConnectionDefName;
FConnection.Connected := True;
Result := True;
FLastError := '';
except
on E: Exception do
FLastError := '连接失败: ' + E.Message;
end;
end;
procedure TDatabaseManager.Disconnect;
begin
if FConnection.Connected then
FConnection.Connected := False;
end;
function TDatabaseManager.ExecSQL(const SQL: string; Params: TArray<TVarRec>): Integer;
var
Query: TFDQuery;
begin
Result := -1;
Query := TFDQuery.Create(nil);
try
Query.Connection := FConnection;
Query.SQL.Text := SQL;
if Length(Params) > 0 then
Query.MacroByName('params').Value := Params;
Query.ExecSQL;
Result := Query.RowsAffected;
finally
Query.Free;
end;
end;
function TDatabaseManager.OpenQuery(const SQL: string; Params: TArray<TVarRec>): TFDQuery;
begin
Result := TFDQuery.Create(nil);
try
Result.Connection := FConnection;
Result.SQL.Text := SQL;
if Length(Params) > 0 then
Result.MacroByName('params').Value := Params;
Result.Open;
except
Result.Free;
raise;
end;
end;
// 私有方法实现
procedure TDatabaseManager.ValidateDriver;
begin
case FDatabaseType of
dtSQLite: FDPhysSQLiteDriverLink.Create(nil);
dtMySQL: FDPhysMySQLDriverLink.Create(nil);
dtPostgreSQL: FDPhysPgDriverLink.Create(nil);
dtMSSQL: FDPhysMSSQLDriverLink.Create(nil);
dtOracle: FDPhysOracleDriverLink.Create(nil);
end;
end;
function TDatabaseManager.GetConnectionDefName: string;
begin
Result := Format('%s_Connection', [GetEnumName(TypeInfo(TDatabaseType), Ord(FDatabaseType))]);
end;
function TDatabaseManager.GetDriverName: string;
begin
case FDatabaseType of
dtSQLite: Result := 'SQLite';
dtMySQL: Result := 'MySQL';
dtPostgreSQL: Result := 'PG';
dtMSSQL: Result := 'MSSQL';
dtOracle: Result := 'Ora';
else
raise Exception.Create('不支持的数据库类型');
end;
end;
function TDatabaseManager.BuildParams(Params: TStrings): string;
var
I: Integer;
begin
Result := '';
for I := 0 to Params.Count - 1 do
Result := Result + Format('%s=%s;', [Params.Names[I], Params.ValueFromIndex[I]]);
end;
end.
使用示例:
// 创建数据库管理器
var
DB: TDatabaseManager;
Params: TStringList;
Query: TFDQuery;
begin
DB := TDatabaseManager.Create;
try
// 配置SQLite连接
Params := TStringList.Create;
try
Params.Values['Database'] := 'C:\Data\mydb.sqlite';
Params.Values['OpenMode'] := 'CreateUTF8';
DB.ConfigureConnection(dtSQLite, Params);
finally
Params.Free;
end;
if DB.Connect then
begin
// 执行SQL命令
DB.ExecSQL('CREATE TABLE IF NOT EXISTS Users (ID INTEGER PRIMARY KEY, Name TEXT)');
// 执行查询
Query := DB.OpenQuery('SELECT * FROM Users');
try
while not Query.Eof do
begin
ShowMessage(Query.FieldByName('Name').AsString);
Query.Next;
end;
finally
Query.Free;
end;
end
else
ShowMessage(DB.LastError);
finally
DB.Free;
end;
end;
功能特点:
- 多数据库支持:
- 支持SQLite、MySQL、PostgreSQL、SQL Server和Oracle
- 通过
TDatabaseType枚举轻松扩展新数据库类型
- 动态配置:
- 安全连接管理:
- 自动验证数据库驱动
- 内置错误处理机制
- 连接资源自动释放
- 灵活的参数化查询:
- 事务支持(可扩展):
配置参数说明:
|
数据库类型 |
必需参数 |
示例值 |
|
SQLite |
Database, OpenMode |
Database=C:\data\test.sdb |
|
MySQL |
Server, Database, User_Name, Password |
Server=192.168.1.100;Port=3306 |
|
PostgreSQL |
Server, Database, User_Name, Password |
Port=5432 |
|
MSSQL |
Server, Database, User_Name, Password |
OSAuthent=Yes |
|
Oracle |
Server, User_Name, Password |
ServiceName=ORCL |
最佳实践建议:
- 连接池配置:
- 性能优化:
- 安全增强:
- 日志记录:
- 多线程支持:
该方案通过面向对象设计实现了以下优势:
1. 高内聚低耦合:数据库操作逻辑与业务逻辑分离
2. 可扩展性:新增数据库类型只需扩展枚举和驱动验证
3. 类型安全:强类型参数减少运行时错误
4. 资源管理:自动释放连接和查询对象
5. 统一接口:所有数据库操作使用相同的方法签名
可根据具体需求扩展以下功能:
- 连接状态监控
- 执行计划分析
- 批量数据操作
- 数据库元数据查询
- 异步操作支持
- 连接故障转移机制

浙公网安备 33010602011771号