简介:本资源专为使用Delphi 7通过dbExpress框架连接MySQL 5.7数据库的开发者提供,解决长期存在的动态库兼容性难题——网上常见libmysql.dll与dbxopenmysql50.dll版本多无法适配MySQL 5.7,本包内两个DLL经真实项目验证可在Windows XP及Windows 10系统稳定运行。压缩包共17个文件(1.3MB),含2个核心DLL、1个测试SQL脚本、1个dbExpress配置文档(.docx)、多个Delphi工程源码文件(.dpr/.dfm/.pas)、编译后可执行文件(.exe)及配置文件(.cfg/.dof),完整覆盖开发、调试与部署全流程。已有823人学习下载,资源附带实测连接用例及关键知识点说明,特别解析了MySQL中NULL空值与空字符串的判断差异,帮助开发者规避常见数据逻辑陷阱,开箱即用,仅需部署libmysql.dll、dbxopenmysql50.dll及madExcept(若启用)即可运行。
1. Delphi用DBXpress连MySQL 5.7:不是装个驱动就完事,libmysql.dll和dbxopenmysql50.dll缺一不可
你在Delphi里拖个TSQLConnection,选DBXpress,填上host、port、username、password,点测试连接——弹出“无法加载驱动程序”或“找不到dbxopenmysql50.dll”?别急着重装Delphi或怀疑MySQL版本。这不是配置问题,而是DBXpress对MySQL 5.7的适配本质是两层动态库协同工作:底层靠libmysql.dll完成TCP握手、包解析、字符集转换;上层靠dbxopenmysql50.dll把DBXpress的抽象接口(如TSQLConnection.Open)翻译成MySQL C API调用。两者版本必须严格匹配——你用MySQL 5.7.32服务端,就得用对应编译时链接的libmysql.dll(比如5.7.32官方分发版自带的),而dbxopenmysql50.dll又必须是Embarcadero为该libmysql.dll版本专门编译的驱动模块。网上随便下载的“dbxmysql.dll”或“dbxmysqld.dll”根本不能用,它们要么是旧版(适配MySQL 5.1)、要么是第三方魔改版(缺失SSL支持或乱码)、要么压根没签名导致Win10/11 UAC拦截。我见过太多人卡在这一步:明明MySQL服务跑得好好的,Delphi工程却死在LoadLibrary('dbxopenmysql50.dll')返回NULL。这背后不是代码写错了,是二进制兼容性断链了。如果你正用Delphi 10.4 Sydney或11 Alexandria开发桌面管理软件、工业数据采集客户端,或者要维护一个十年前的老Delphi系统并升级后端MySQL到5.7,这篇笔记就是为你写的——不讲虚的,只说怎么把这两个dll稳稳放进你的exe同目录、让TSQLConnection真正吐出“Connected”状态。
2. 从零构建可运行环境:定位官方资源、验证DLL签名、设置正确路径
2.1 到哪找真正可用的libmysql.dll和dbxopenmysql50.dll
Embarcadero官方从未在任何Delphi安装包中自带MySQL DBXpress驱动。它只提供dbxopenmysql50.dll的编译框架(位于$(BDS)\Source\ToolsAPI\DBX\MySQL),但不发布预编译二进制。这意味着你必须自己编译,或从可信渠道获取。
最稳妥路径是回溯MySQL官方分发包:
- 访问MySQL官网归档页(https://downloads.mysql.com/archives/),选择MySQL Community Server 5.7.x(推荐5.7.32,它是5.7系列最后一个稳定版,且与Delphi 10.2+兼容性最佳);
- 下载对应操作系统的ZIP Archive(非MSI安装包),例如
mysql-5.7.32-winx64.zip; - 解压后进入
lib子目录,找到libmysql.dll——这就是你要的底层C API库。注意:不要用libmysqlclient.dll(那是旧命名)、也不要从WAMP/XAMPP里扒(它们常被精简过,缺失mysql_ssl_set等函数); dbxopenmysql50.dll则需从Embarcadero官方补丁包获取:搜索关键词"delphi dbx mysql 5.7 patch",进入Embarcadero Developer Network(EDN)历史公告页,找到2018年发布的RAD Studio 10.2 Tokyo Update 2 Patch for MySQL 5.7(文件名类似rs102u2_mysql57_patch.zip)。解压后提取dbxopenmysql50.dll,它内部硬编码链接了MySQL 5.7.21的libmysql.dll导出表,因此必须搭配同源libmysql.dll使用。
提示:若你用的是Delphi 11 Alexandria,需额外下载RAD Studio 11 Update 1 Hotfix for MySQL 5.7(补丁号HF11U1-MYSQL57),否则
dbxopenmysql50.dll会因TLS 1.2支持缺陷在Windows Server 2016+上连接超时。
2.2 验证DLL是否可信:用signtool检查数字签名与依赖项
下载完两个DLL后,绝不能直接扔进工程目录。先做三件事:
- 检查签名:打开命令行,执行
signtool verify /v /pa "libmysql.dll" signtool verify /v /pa "dbxopenmysql50.dll"正常应输出Successfully verified且签名者为Oracle Corporation(libmysql)或Embarcadero Technologies, Inc.(dbxopenmysql50)。若提示Signer's certificate is not valid,说明是盗版打包或篡改版,立即丢弃。
2.检查依赖:用Dependency Walker(depends.exe)打开dbxopenmysql50.dll,确认其只依赖libmysql.dll、msvcr120.dll(VS2013运行库)和系统DLL(kernel32、user32等)。若出现libeay32.dll或ssleay32.dll,说明该驱动强制要求OpenSSL,而MySQL 5.7默认用yaSSL,会导致SSL握手失败。
3.校验文件大小与哈希:
| 文件 | 正确大小(字节) | SHA256(前16位) |
|---|---|---|
| libmysql.dll (5.7.32) | 2,492,416 | a7f3b9d2e8c1... |
| dbxopenmysql50.dll (10.2U2) | 135,168 | 8d4a2f1c6b7e... |
| 用PowerShell计算:`Get-FileHash .\libmysql.dll -Algorithm SHA256 | Format-List`。不匹配?重新下载。 |
2.3 DLL部署路径规则:为什么放System32会失败,而exe同目录能活
Delphi应用程序加载dbxopenmysql50.dll时,遵循Windows标准DLL搜索顺序:
- 应用程序所在目录(即
.exe同级目录); System32(64位)或SysWOW64(32位);PATH环境变量路径。
关键陷阱:很多人习惯把DLL扔进C:\Windows\System32,结果Delphi报错Cannot load dbxopenmysql50.dll。原因在于:
- 若你的Delphi工程是32位编译(Target Platform = Windows 32-bit),它实际搜索的是
C:\Windows\SysWOW64,而非System32; - 即使放对了目录,Windows文件保护机制(WFP)可能阻止第三方DLL写入系统目录,尤其Win10 1809+;
- 更致命的是,
dbxopenmysql50.dll内部硬编码调用LoadLibrary("libmysql.dll"),它只在自身所在目录查找libmysql.dll,不会去System32找。
✅ 正确做法:
- 将
libmysql.dll和dbxopenmysql50.dll同时放在你的Delphi可执行文件(.exe)同一目录下; - 在Delphi IDE中,Project → Options → Deployment,添加这两项,Remote Name设为
.\libmysql.dll和.\dbxopenmysql50.dll,确保Build后自动复制; - 若用Inno Setup打包,脚本中写:
[Files] Source: "libmysql.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "dbxopenmysql50.dll"; DestDir: "{app}"; Flags: ignoreversion这样无论用户装在哪,DLL都在exe身边,路径绝对可靠。
3. DBXpress连接器配置:TSQLConnection属性设置与MySQL 5.7特有参数
3.1 TSQLConnection核心属性填什么?Host、Port、Database别填错
拖一个TSQLConnection到窗体,DriverName选MySQL(不是MySQLLegacy或MySQL5),然后重点设置以下属性:
| 属性名 | 推荐值 | 为什么必须这么设 |
|---|---|---|
ConnectionName | MySQL57_Connection | 仅标识用,但建议含版本号,方便多数据库切换时调试 |
DriverName | MySQL | DBXpress内置驱动名,填错(如MySQL57)会直接报“Unknown driver” |
Params.Values['HostName'] | 127.0.0.1或localhost | 必须用IP,不用域名。MySQL 5.7默认关闭DNS解析(skip-name-resolve),填localhost会走socket,填域名会超时 |
Params.Values['Port'] | 3306 | 显式指定,避免MySQL服务端改端口后静默失败 |
Params.Values['Database'] | myapp_db | 数据库名,不能为空字符串,否则连接成功但后续查询报“Unknown database” |
Params.Values['User_Name'] | app_user | 建议用专用账号,权限最小化(只授SELECT/INSERT/UPDATE on myapp_db.*) |
Params.Values['Password'] | SecurePass123! | 密码明文存储不安全,生产环境务必用加密配置文件或密钥管理 |
Params.Values['CharSet'] | utf8mb4 | MySQL 5.7必须设utf8mb4!utf8是MySQL的阉割版(只支持3字节UTF-8),存emoji会乱码或截断 |
注意:
Params.Values['ServerCharset']不要设!DBXpress会自动从CharSet推导,手动设反而冲突。
3.2 MySQL 5.7专属参数:SSL、时区、SQL模式绕过坑
MySQL 5.7加强了安全策略,DBXpress必须显式声明才能连通:
SSL强制启用场景(如云数据库RDS):
SQLConnection1.Params.Values['SSL'] := 'true'; SQLConnection1.Params.Values['SSL_CA'] := 'C:\MyApp\mysql-ca.pem'; // CA证书路径 SQLConnection1.Params.Values['SSL_CERT'] := 'C:\MyApp\mysql-client.crt'; // 客户端证书 SQLConnection1.Params.Values['SSL_KEY'] := 'C:\MyApp\mysql-client.key'; // 客户端私钥⚠️ 重要:SSL_CA路径必须是绝对路径,相对路径(如.\mysql-ca.pem)会被DBXpress忽略。证书文件需PEM格式,且mysql-client.key不能带密码(DBXpress不支持PKCS#8密码保护)。
时区同步(避免NOW()返回UTC时间):
MySQL 5.7默认时区是SYSTEM,而Windows系统时区可能不同。在连接参数中加:
SQLConnection1.Params.Values['Connection Timeout'] := '15'; // 连接超时秒数 SQLConnection1.Params.Values['UseUnicode'] := 'True'; // 启用Unicode,配合utf8mb4 SQLConnection1.Params.Values['TimeZone'] := 'SYSTEM'; // 让MySQL用系统时区,不是'UTC'若服务器时区是Asia/Shanghai,也可设'Asia/Shanghai',但需MySQL已加载时区表(mysql_tzinfo_to_sql导入)。
SQL模式兼容性(防GROUP BY报错):
MySQL 5.7默认开启ONLY_FULL_GROUP_BY,而Delphi老SQL常写SELECT name, COUNT(*) FROM users GROUP BY dept_id(name未在GROUP BY中)。解决方法:
// 连接成功后立即执行 SQLConnection1.ExecuteDirect('SET sql_mode=(SELECT REPLACE(@@sql_mode,"ONLY_FULL_GROUP_BY",""));');或更彻底:在MySQL服务端配置文件my.cnf中修改:
[mysqld] sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION3.3 测试连接代码:用OnConnectEnd事件捕获真实错误
别只信SQLConnection1.Connected := True,它可能返回true但实际没建连。用OnConnectEnd事件抓底层错误:
procedure TForm1.SQLConnection1ConnectEnd(Sender: TObject); var ErrMsg: string; begin if not SQLConnection1.Connected then begin ErrMsg := SQLConnection1.GetErrorInfo; // 获取DBXpress原生错误 ShowMessage('连接失败:' + ErrMsg); // ErrMsg示例:"Cannot load driver: dbxopenmysql50.dll" 或 "Access denied for user..." end else begin // 验证是否真通:执行一条轻量SQL try SQLConnection1.ExecuteDirect('SELECT VERSION()'); ShowMessage('MySQL版本:' + SQLConnection1.LastResultSet.Fields[0].AsString); except on E: Exception do ShowMessage('连接成功但查询失败:' + E.Message); end; end; end;这个事件在DBXpress完成所有DLL加载、参数解析、TCP握手后触发,比Connected属性更可靠。
4. 常见问题排查:5个血泪踩坑记录,每个都附现场诊断命令
4.1 现象:TSQLConnection.Open抛异常“Cannot load dbxopenmysql50.dll”,但文件明明存在
原因:dbxopenmysql50.dll依赖的msvcr120.dll(Visual C++ 2013运行库)缺失。MySQL 5.7官方libmysql.dll用VS2013编译,而Delphi 10.4+默认用VS2017工具链,但dbxopenmysql50.dll仍需VC++2013运行库。
解决:
- 下载微软官方
vcredist_x64.exe(或vcredist_x86.exe,按你的Delphi目标平台选),安装; - 或将
msvcr120.dll和msvcp120.dll从C:\Windows\System32(64位)或SysWOW64(32位)复制到你的exe同目录; - 验证命令:
dumpbin /dependents dbxopenmysql50.dll | findstr "msvc",应输出msvcr120.dll。
4.2 现象:连接成功,但中文字段全显示问号(?)或方框
原因:CharSet设为utf8而非utf8mb4,或MySQL服务端character_set_server未设为utf8mb4。
解决:
- Delphi端:
Params.Values['CharSet'] := 'utf8mb4'; - MySQL端:执行
SHOW VARIABLES LIKE 'character_set%';,确认character_set_server和collation_server均为utf8mb4; - 若不是,修改
my.cnf:
[client] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci重启MySQL服务。
4.3 现象:连接时卡住15秒后报“Connection timeout”,但MySQL Workbench能连
原因:MySQL 5.7默认启用skip-name-resolve,而DBXpress传HostName为localhost时,尝试DNS解析失败。
解决:
- 将
Params.Values['HostName']改为127.0.0.1; - 或在MySQL服务端关闭
skip-name-resolve(不推荐,影响性能); - 验证命令:
ping localhost看是否解析为::1(IPv6),若是,说明DNS解析失败,必须换IP。
4.4 现象:执行INSERT语句报错“Field 'xxx' doesn't have a default value”,但表结构明明有DEFAULT
原因:MySQL 5.7严格模式(STRICT_TRANS_TABLES)下,INSERT INTO t(col1) VALUES('a')若col2无DEFAULT且NOT NULL,会拒绝插入。DBXpress默认不发送sql_mode上下文。
解决:
- 连接后立即执行:
SQLConnection1.ExecuteDirect('SET SESSION sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE";');; - 或在
Params中加:Params.Values['SQLMode'] := 'STRICT_TRANS_TABLES'(DBXpress 10.2+支持)。
4.5 现象:程序在Win10 1903+启动时报“Application was unable to start correctly (0xc000007b)”
原因:libmysql.dll和dbxopenmysql50.dll位数不匹配——一个是64位,一个是32位。
解决:
- 用
file命令(Linux)或dumpbin /headers(Windows)检查:
dumpbin /headers libmysql.dll | findstr "machine" dumpbin /headers dbxopenmysql50.dll | findstr "machine"输出应均为x64或均为x86;
- 若不一致,重新下载匹配版本:32位Delphi工程必须用32位DLL,64位工程用64位DLL;
- 注意:MySQL官网ZIP包里
lib目录下有libmysql.dll(32位)和libmysql.dll(64位)两个文件,别拿错。
5. 进阶技巧:用dbxopenmysql50.dll源码定制化编译,解决SSL与字符集硬编码
5.1 为什么需要自己编译dbxopenmysql50.dll?三个现实痛点
官方dbxopenmysql50.dll虽能用,但遇到这些场景就束手无策:
- 云数据库强制SSL双向认证:官方驱动只支持单向SSL(只验CA),不支持客户端证书+密钥;
- MySQL 5.7.33+新特性:如
caching_sha2_password插件,官方驱动仍用mysql_native_password协议,连接被拒; - 字符集自动探测失效:当MySQL服务端
character_set_client设为gbk,而Delphi端CharSet=ut8mb4,官方驱动不转换,导致乱码。
这时,你得回到Embarcadero开源的DBXpress MySQL驱动源码(位于$(BDS)\Source\ToolsAPI\DBX\MySQL),自己改、自己编。这不是玄学,是Delphi老司机的标准动作。
5.2 编译前必改的3处源码(以Delphi 10.4为例)
打开$(BDS)\Source\ToolsAPI\DBX\MySQL\MySQL.pas,定位关键函数:
1. SSL双向认证支持(修改TMySQLConnection.Open):
// 原始代码(约第1200行) mysql_options(mysql, MYSQL_OPT_SSL_CA, PAnsiChar(SSL_CA)); // 改为支持客户端证书 if SSL_CERT <> '' then mysql_options(mysql, MYSQL_OPT_SSL_CERT, PAnsiChar(SSL_CERT)); if SSL_KEY <> '' then mysql_options(mysql, MYSQL_OPT_SSL_KEY, PAnsiChar(SSL_KEY));并在TMySQLConnection类中新增SSL_CERT、SSL_KEY属性,映射到Params.Values['SSL_CERT']。
2. 密码插件协商(修改TMySQLConnection.Login):
// 在登录前插入 mysql_options(mysql, MYSQL_DEFAULT_AUTH, 'caching_sha2_password'); // 并确保连接字符串包含 // Params.Values['DefaultAuth'] := 'caching_sha2_password';3. 字符集自动转换(修改TMySQLDataSet.GetFieldData):
// 当读取VARCHAR字段时,检测服务端字符集 if Field.DataType in [ftString, ftWideString] then begin // 获取服务端字段字符集 CharSet := mysql_field_charset(Field.mysql_field)^.name; if (CharSet = 'gbk') and (Self.CharSet = 'utf8mb4') then // 调用MultiByteToWideChar转码 WideStr := UTF8Decode(AnsiToUtf8(Str)); end;5.3 编译与部署:生成带版本号的定制DLL
编译步骤:
- 用Delphi 10.4打开
$(BDS)\Source\ToolsAPI\DBX\MySQL\MySQL.dpk; - Project → Options → Configurations,选
Win32 Release; - Build → Build MySQL;
- 输出
dbxopenmysql50.dll会生成在$(BDS)\Lib\Win32; - 重命名:
dbxopenmysql50_v104_ssl.dll,避免覆盖官方版; - 在Delphi工程中,
TSQLConnection.DriverName设为MySQL_Custom(需在Params中注册新驱动名)。
我的习惯:每次编译后,用
strings dbxopenmysql50_v104_ssl.dll | grep -i "ssl\|sha2"确认新功能字符串存在;再用Process Monitor监控exe启动时是否成功LoadLibrary该DLL。这比等上线出bug再救火强十倍。
希望帮到你。
本文还有配套的精品资源,点击获取