You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请教:如何基于Delphi Community Edition构建通用数据库操作解决方案?

用Delphi Community Edition构建通用数据库操作解决方案

一、组件选择推荐

FireDAC(优先推荐)

  • 官方原生支持MSSQL、MySQL、PostgreSQL、Oracle等主流数据库,对于Vertica、GreenPlum可通过ODBC驱动或第三方适配插件兼容
  • 自带连接池、SQL预处理、跨数据库语法兼容层,配置灵活,完全适配Delphi Community Edition免费授权
  • 调试工具完善,IDE内可直接测试连接、执行SQL,降低开发成本

dbExpress

  • 轻量级组件,适合简单场景,但对Vertica、GreenPlum这类数据库原生支持不足,需额外寻找第三方驱动,优先级低于FireDAC

二、最佳实践指导

  • 抽象数据访问层:封装通用CRUD、连接管理、事务逻辑,业务代码仅调用抽象接口,避免直接依赖特定数据库组件,便于后续切换数据源
  • 强制参数化查询:绝对禁止拼接SQL字符串,使用TFDQuery.ParamByName传递参数,同时防止SQL注入、提升执行效率
  • 启用连接池:通过FireDAC的TFDConnectionPool复用数据库连接,减少频繁建立/断开连接的性能损耗
  • 适配数据库语法差异:针对不同数据库的分页、函数语法(如MySQLLIMIT、MSSQLOFFSET/FETCH、OracleROWNUM),封装统一的适配函数
  • 统一错误处理:捕获数据库异常并转换为业务友好的错误信息,同时记录详细日志(含SQL语句、参数值)

三、代码示例

1. 通用数据库连接封装

unit DBConnection;

interface

uses
  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.Phys.MySQL, FireDAC.Phys.MSSQL, FireDAC.Phys.PostgreSQL,
  FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
  FireDAC.DApt, FireDAC.Comp.DataSet, FireDAC.Comp.Client, System.SysUtils;

type
  TDBType = (dtMySQL, dtMSSQL, dtPostgreSQL, dtOracle, dtVertica);

  TDBConnection = class
  private
    FConnection: TFDConnection;
    procedure ConfigureConnection(DBType: TDBType; const Server, DBName, UserName, Password: string);
  public
    constructor Create(DBType: TDBType; const Server, DBName, UserName, Password: string);
    destructor Destroy; override;
    function CreateQuery: TFDQuery;
    procedure BeginTrans;
    procedure CommitTrans;
    procedure RollbackTrans;
    property Connection: TFDConnection read FConnection;
  end;

implementation

constructor TDBConnection.Create(DBType: TDBType; const Server, DBName, UserName, Password: string);
begin
  inherited Create;
  FConnection := TFDConnection.Create(nil);
  FConnection.LoginPrompt := False;
  ConfigureConnection(DBType, Server, DBName, UserName, Password);
  FConnection.Connected := True;
end;

destructor TDBConnection.Destroy;
begin
  FConnection.Free;
  inherited;
end;

procedure TDBConnection.ConfigureConnection(DBType: TDBType; const Server, DBName, UserName, Password: string);
begin
  case DBType of
    dtMySQL:
      begin
        FConnection.DriverName := 'MySQL';
        FConnection.Params.Values['Server'] := Server;
        FConnection.Params.Values['Database'] := DBName;
        FConnection.Params.Values['User_Name'] := UserName;
        FConnection.Params.Values['Password'] := Password;
        FConnection.Params.Values['CharacterSet'] := 'utf8mb4';
      end;
    dtMSSQL:
      begin
        FConnection.DriverName := 'MSSQL';
        FConnection.Params.Values['Server'] := Server;
        FConnection.Params.Values['Database'] := DBName;
        FConnection.Params.Values['User_Name'] := UserName;
        FConnection.Params.Values['Password'] := Password;
      end;
    dtPostgreSQL:
      begin
        FConnection.DriverName := 'PostgreSQL';
        FConnection.Params.Values['Server'] := Server;
        FConnection.Params.Values['Database'] := DBName;
        FConnection.Params.Values['User_Name'] := UserName;
        FConnection.Params.Values['Password'] := Password;
      end;
    dtVertica:
      begin
        FConnection.DriverName := 'ODBC';
        FConnection.Params.Values['Driver'] := 'Vertica ODBC Driver';
        FConnection.Params.Values['Server'] := Server;
        FConnection.Params.Values['Database'] := DBName;
        FConnection.Params.Values['UID'] := UserName;
        FConnection.Params.Values['PWD'] := Password;
      end;
    // 其他数据库配置可在此扩展
  end;
end;

function TDBConnection.CreateQuery: TFDQuery;
begin
  Result := TFDQuery.Create(nil);
  Result.Connection := FConnection;
end;

procedure TDBConnection.BeginTrans;
begin
  FConnection.StartTransaction;
end;

procedure TDBConnection.CommitTrans;
begin
  FConnection.Commit;
end;

procedure TDBConnection.RollbackTrans;
begin
  FConnection.Rollback;
end;

end.

2. 通用CRUD操作示例

// 查询数据
function GetActiveUsers(DBConn: TDBConnection; out UserNames: TArray<string>): Boolean;
var
  Query: TFDQuery;
  I: Integer;
begin
  Result := False;
  Query := DBConn.CreateQuery;
  try
    Query.SQL.Text := 'SELECT user_name FROM sys_users WHERE is_active = :IsActive';
    Query.ParamByName('IsActive').AsBoolean := True;
    Query.Open;
    
    SetLength(UserNames, Query.RecordCount);
    I := 0;
    while not Query.Eof do
    begin
      UserNames[I] := Query.FieldByName('user_name').AsString;
      Query.Next;
      Inc(I);
    end;
    Result := True;
  finally
    Query.Free;
  end;
end;

// 插入数据(带事务)
function AddUser(DBConn: TDBConnection; const UserName, Email: string): Boolean;
var
  Query: TFDQuery;
begin
  Result := False;
  Query := DBConn.CreateQuery;
  try
    DBConn.BeginTrans;
    try
      Query.SQL.Text := 'INSERT INTO sys_users (user_name, email) VALUES (:UserName, :Email)';
      Query.ParamByName('UserName').AsString := UserName;
      Query.ParamByName('Email').AsString := Email;
      Query.ExecSQL;
      
      DBConn.CommitTrans;
      Result := True;
    except
      DBConn.RollbackTrans;
      raise;
    end;
  finally
    Query.Free;
  end;
end;

四、入门资源

  • FireDAC官方手册:直接在Delphi IDE的帮助菜单中访问,包含驱动配置、API详解、常见问题解决方案
  • Delphi内置示例:IDE自带的FireDAC demo项目,覆盖连接配置、数据集操作、事务管理等核心场景
  • 社区教程:搜索Delphi FireDAC通用数据访问层的实现案例,参考成熟项目的封装思路

内容的提问来源于stack exchange,提问作者Alex S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 19:12:40