使用FireDAC的TFDManager和TFDConnection组件实现运行时动态数据库连接

news/2025/11/5 17:04:35/文章来源:https://www.cnblogs.com/karkash/p/19194201

以下是一个通用的数据库连接方案,使用FireDAC的TFDManagerTFDConnection组件实现运行时动态数据库连接。支持多种数据库类型,采用面向对象封装:

 

unit DatabaseManager;interfaceusesSystem.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;typeTDatabaseType = (dtSQLite, dtMySQL, dtPostgreSQL, dtMSSQL, dtOracle);TDatabaseManager = classprivateFConnection: TFDConnection;FManager: TFDManager;FDatabaseType: TDatabaseType;FLastError: string;procedure ValidateDriver;function GetConnectionDefName: string;function GetDriverName: string;function BuildParams(Params: TStrings): string;publicconstructor 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;
beginFManager := TFDManager.Create(nil);FConnection := TFDConnection.Create(nil);FManager.SilentMode := True;FManager.Active := True;
end;destructor TDatabaseManager.Destroy;
beginDisconnect;FConnection.Free;FManager.Free;inherited;
end;procedure TDatabaseManager.ConfigureConnection(DatabaseType: TDatabaseType; Params: TStrings);
beginFDatabaseType := DatabaseType;FManager.ConnectionDefs.Clear;// 添加新的连接定义FManager.AddConnectionDef(GetConnectionDefName,GetDriverName,BuildParams(Params));
end;function TDatabaseManager.Connect: Boolean;
beginResult := False;tryValidateDriver;FConnection.ConnectionDefName := GetConnectionDefName;FConnection.Connected := True;Result := True;FLastError := '';excepton E: Exception doFLastError := '连接失败: ' + E.Message;end;
end;procedure TDatabaseManager.Disconnect;
beginif FConnection.Connected thenFConnection.Connected := False;
end;function TDatabaseManager.ExecSQL(const SQL: string; Params: TArray<TVarRec>): Integer;
varQuery: TFDQuery;
beginResult := -1;Query := TFDQuery.Create(nil);tryQuery.Connection := FConnection;Query.SQL.Text := SQL;if Length(Params) > 0 thenQuery.MacroByName('params').Value := Params;Query.ExecSQL;Result := Query.RowsAffected;finallyQuery.Free;end;
end;function TDatabaseManager.OpenQuery(const SQL: string; Params: TArray<TVarRec>): TFDQuery;
beginResult := TFDQuery.Create(nil);tryResult.Connection := FConnection;Result.SQL.Text := SQL;if Length(Params) > 0 thenResult.MacroByName('params').Value := Params;Result.Open;exceptResult.Free;raise;end;
end;// 私有方法实现
procedure TDatabaseManager.ValidateDriver;
begincase FDatabaseType ofdtSQLite: 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;
beginResult := Format('%s_Connection', [GetEnumName(TypeInfo(TDatabaseType), Ord(FDatabaseType))]);
end;function TDatabaseManager.GetDriverName: string;
begincase FDatabaseType ofdtSQLite: Result := 'SQLite';dtMySQL: Result := 'MySQL';dtPostgreSQL: Result := 'PG';dtMSSQL: Result := 'MSSQL';dtOracle: Result := 'Ora';elseraise Exception.Create('不支持的数据库类型');end;
end;function TDatabaseManager.BuildParams(Params: TStrings): string;
varI: Integer;
beginResult := '';for I := 0 to Params.Count - 1 doResult := Result + Format('%s=%s;', [Params.Names[I], Params.ValueFromIndex[I]]);
end;end.

 

使用示例:

 

// 创建数据库管理器
varDB: TDatabaseManager;Params: TStringList;Query: TFDQuery;
beginDB := TDatabaseManager.Create;try// 配置SQLite连接Params := TStringList.Create;tryParams.Values['Database'] := 'C:\Data\mydb.sqlite';Params.Values['OpenMode'] := 'CreateUTF8';DB.ConfigureConnection(dtSQLite, Params);finallyParams.Free;end;if DB.Connect thenbegin// 执行SQL命令DB.ExecSQL('CREATE TABLE IF NOT EXISTS Users (ID INTEGER PRIMARY KEY, Name TEXT)');// 执行查询Query := DB.OpenQuery('SELECT * FROM Users');trywhile not Query.Eof dobeginShowMessage(Query.FieldByName('Name').AsString);Query.Next;end;finallyQuery.Free;end;endelseShowMessage(DB.LastError);finallyDB.Free;end;
end;

 

功能特点:

 

  1. 多数据库支持
    • 支持SQLite、MySQL、PostgreSQL、SQL Server和Oracle
    • 通过TDatabaseType枚举轻松扩展新数据库类型
  2. 动态配置
  3.  
  4. 安全连接管理
    • 自动验证数据库驱动
    • 内置错误处理机制
    • 连接资源自动释放
  5. 灵活的参数化查询
  6.  
  7. 事务支持(可扩展):
  8.  

 

配置参数说明:

 

数据库类型

必需参数

示例值

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. 安全增强
  6.  
  7. 日志记录
  8.  
  9. 多线程支持
  10.  

 

该方案通过面向对象设计实现了以下优势:

1. 高内聚低耦合:数据库操作逻辑与业务逻辑分离

2. 可扩展性:新增数据库类型只需扩展枚举和驱动验证

3. 类型安全:强类型参数减少运行时错误

4. 资源管理:自动释放连接和查询对象

5. 统一接口:所有数据库操作使用相同的方法签名

 

可根据具体需求扩展以下功能:

 

  • 连接状态监控
  • 执行计划分析
  • 批量数据操作
  • 数据库元数据查询
  • 异步操作支持
  • 连接故障转移机制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/956961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

laas paas saas 架构说明

--------------------------------------------------------------------------------------------------------------------------- 在 Java 开发领域,IaaS、PaaS、SaaS 分别对应基础设施、平台、软件三个层级的服务…

Delphi RESTful API

服务器 第一步: 创建Delphi REST服务器(使用WebBroker或DataSnap,这里使用WebBroker)在 Delphi 中创建 "Stand-alone Web Server Application" 将 API 代码粘贴到 WebModule 中 设置端口(默认为 8080)…

TFDMemTable 是断开性数据集

TFDMemTable 是断开性数据集,数据存储在内存中,无需实时连接数据库它适用于缓存数据、离线操作、临时数据处理等场景 虽然 TFDMemTable 是断开性的,但它仍然可以通过 TFDQuery 等组件与数据库进行数据交互

2025年河南公共走廊全钢防火隔断公司权威推荐榜单:商场全钢防火隔断/公共走廊防火隔断/公共走廊防火隔墙源头厂家精选

在商业建筑、学校、医院等公共空间,全钢防火隔断作为保障人员安全疏散的关键设施,其防火性能与结构稳定性直接关系到生命财产安全。根据建筑防火行业统计,2025年国内防火建材市场规模预计突破800亿元,其中全钢防火…

2025年板式换热机组制造厂权威推荐榜单:容积式换热机组/热力机组/换热机组源头厂家精选

在工业节能改造与区域能源管理加速推进的背景下,板式换热机组凭借其高效传热、紧凑结构及智能控制等优势,已成为区域供暖、化工流程及建筑能源系统的核心装备。根据行业数据统计,2025年国内换热机组市场规模预计突破…

十四.JavaScript 简介及导入方式

十四.JavaScript 简介及导入方式 定义:JS导入方式:有两种 显示:Fn+F12-->Console内联(script)外联:创建.js文件-导入.js文件基本输入输出: 打印到控制窗口:console.log() 显示到下拉框:alert() 十五.Java…

2025 年 11 月音乐喷泉工程,景区互动音乐喷泉,彩色灯光音乐喷泉厂家最新推荐,聚焦资质、案例、售后的五家机构深度解读!

引言 近期,专业景观行业协会针对音乐喷泉工程、景区互动音乐喷泉、彩色灯光音乐喷泉领域开展了 2025 年度厂家测评工作,本次测评覆盖行业内百余家主流企业,通过资质审核、技术实力评估、项目案例考察、售后服务调研…

11.5 NOIP 模拟赛 T1. 荣耀

思路 \(f(n)\): \(n\) 个位置中 \(0\) 号勋章出现偶数次的方案数 \(g(n)\): \(n\) 个位置中 \(0\) 号勋章出现奇数次的方案数 \[f(n) = m \cdot f(n-1) + g(n-1) \\ g(n) = f(n-1) + m \cdot g(n-1) \]可以 \[\begin{b…

智能体自动化 ui 测试

智能体自动化 ui 测试

Windows开机自动播放视频设置

打开计划任务程序 有两种方法打开输入命令 运行输入taskschd.msc开始菜单 Windows管理工具-计划任务程序设置开机任务 创建任务设置任务名称设置触发器 需设置延迟任务时间否则可能开机页面闪一下但是不启动设置操作启…

快速创建模拟 REST API

JSON Server 是一个用于快速创建模拟 REST API 的工具,主要用在前端开发和原型设计中。 主要特点 零编码:只需一个 JSON 文件即可创建完整的 API RESTful:自动提供完整的 REST API 端点 真实 HTTP:使用真实的 HTTP…

CSS简介及导入方式

简介:css语法:选择器放在head中间 CSS三种导入方式:九、CSS选择器 定义、类型:1-4:5-6:7-8:伪元素选择器 十、CSS常用属性 font:字体的复合属性 line-height:行高 行内块元素:十一、盒子模型 概念:实现:十二…

2025 年 11 月倍捻机,直捻机,大卷装倍捻机厂家最新推荐,实力品牌深度解析采购无忧之选!

引言 近期,行业权威协会针对倍捻机、直捻机、大卷装倍捻机领域开展了全面测评,测评覆盖近 50 家主流厂家,从技术参数、生产稳定性、节能表现、售后服务等 12 项核心指标进行量化打分,最终筛选出综合实力突出的品牌…

皮试

皮试结果

使用rsync及inotify实现两台Linux设备间的文件夹同步

一、背景 环境 由于业务需要,软件需要在CentOS 6.10 32位环境中进行编译。由于系统版本较老,无法实现使用vscode远程连接到CentOS上进行软件开发。为了仍能享受到vscode的便利,现借助SUSE作为vscode远程连接的开发环…

教育部等七部门关于加强中小学科技教育的意见-解读

这份《教育部等七部门关于加强中小学科技教育的意见》(教基〔2025〕7号)是国家层面推动中小学科技教育系统化、高质量发展的纲领性文件,体现了国家对科技创新人才培养的高度重视和战略布局。作为青少年编程教育科技…

2025年酒柜定制厂排名:酒柜定制选择哪家好?

葡萄酒收藏已从小众爱好演变为彰显品味的生活方式,而专业酒柜则是守护美酒价值的核心载体。面对市场上良莠不齐的酒柜定制服务,如何找到真正靠谱的酒柜定制厂?本文基于行业调研与用户反馈,精选2025年十大酒柜定制厂…

2025 年 11 月智能倍捻机,节能倍捻机,高速大卷装倍捻机厂家最新推荐,实力品牌深度解析采购无忧之选!

引言 当前纺机行业对智能倍捻机、节能倍捻机、高速大卷装倍捻机的需求持续攀升,为帮助企业精准选择优质设备,行业权威协会开展专项测评,从技术参数、生产效率、能耗表现、售后服务等 8 大维度,对 50 余家厂家的设备…

AT_arc188_d [ARC188D] Mirror and Order

题目大意 我们称两个长度为 \(n\) 的数组所构成的数组对 \((a, b)\) 是合法的当且仅当其能够满足以下构造:构造 \(n\) 个长度为 \(3\) 且对应每一位上都不重复的使用了 \(1 \sim n\) 中的元素的数组 \(s_i\),我们令第…

西门子实物图64 dq a0 B0排查

西门子实物图64 dq a0 B0排查