简介:一套针对Delphi 7通过dbExpress连接MySQL 5.7的可用动态库包,专为解决网上常见驱动缺失、连接失败问题而整理,适合使用老版本Delphi开发数据库应用、需要升级或迁移MySQL环境的开发者。压缩包共17个文件,包含dll动态库、可执行测试用例、SQL脚本、工程源码(pas/dfm/dpr)及配置说明文档等,包体仅1.3MB,便于快速部署。其中libmysql.dll与dbxopenmysql50.dll已通过作者项目实测,并附带演示如何区分数据库字段的空值与空字符串,避免常见判断误区。程序可在Windows XP与Windows 10下运行,发布时只需携带两个dll及midas库。已有826人学习下载,适合直接复用或参考实现细节。1. Delphi老项目连不上MySQL 5.7:一份动态库资源解了燃眉之急如果你还在维护Delphi老系统,大概率撞过这堵墙:服务端数据库从MySQL 5.0升到5.7,客户端程序没动,TSQLConnection连上去直接报“Cannot Load DBX Driver”或者打开后闪退。我接手的老项目就栽在这上面,折腾一整天,最后发现解法朴实到不敢相信——把libmysql.dll和dbxopenmysql50.dll两个动态库放到程序exe同目录,dbExpress就能正常走MySQL 5.7的协议。这篇文章把这段踩坑过程完整拆开:两个DLL各管什么、怎么部署、连接参数怎么定、哪些坑必踩。适合正在用dbExpress连MySQL 5.7的老项目维护者,也适合刚做完数据库升级、客户端还没适配的团队。2. 两个DLL的分工:从MySQL 5.0到5.7的dbExpress兼容方案2.1 dbExpress驱动链路:应用程序到底需要几层库dbExpress是Delphi早期的跨数据库访问层,它本身不是一个连接程序,而是一套框架。你在窗体上拖一个TSQLConnection,设置好DriverName,剩下的脏活全由框架转给底层的厂家驱动。不同数据库对应不同的驱动动态库,MySQL这边就是dbxopenmysql50.dll。把这条链路记住,后面所有排查都靠它:Delphi应用 ↓ TSQLConnection组件 dbxopenmysql50.dll (dbExpress驱动) ↓ MySQL C API调用 libmysql.dll (MySQL客户端连接库) ↓ TCP 3306 MySQL Server 5.7dbxopenmysql50.dll负责把dbExpress的调用转换成MySQL C API函数调用,例如mysql_init、mysql_real_connect、mysql_query等。但C API这些函数的实体并不在这个驱动里,而在MySQL官方提供的libmysql.dll中。换句话说,驱动文件只负责翻译,网络协议真正干活的是客户端库。所以缺了任何一个文件,整条链路都断。我见过不少人在第一步就搞错,把dbxopenmysql50.dll当成万能钥匙,连上后提示Invalid vendor library或LoadLibrary失败,然后开始怀疑版本。其实只要链路图在脑子里,这类报错扫一眼就知道是缺了libmysql.dll。2.2 MySQL 5.7为什么能沿用5.0的驱动第一次拿到这份资源的人都会有同样的疑问:文件名里的“openmysql50”明显是给MySQL 5.0用的,接5.7真的行?实测下来是可行的,这背后有技术原因。MySQL C API的公开接口从5.0到5.7没有破坏性变更。驱动里调用的mysql_real_connect、mysql_query、mysql_store_result这些老牌函数,在5.7的libmysql.dll里依然原样导出。dbExpress驱动本身不关心MySQL服务端的小版本号,它只按C API标准函数签名去加载libmysql.dll的导出表。只要libmysql.dll换成5.7配套编译的那一版,驱动文件本身不动,就能连上5.7的服务端。也有人换过FireDAC或第三方组件来绕开dbExpress链路。不是不行,但老项目里的TSQLQuery、TSQLStoredProc、TDataSetProvider一堆组件全要改,数据字典、字段类型映射也要重新调。我评估过,改动量太大,远不如保留dbExpress架构、只换libmysql.dll划算。这份资源的价值正在于,它能让你一行业务代码不改就完成MySQL版本兼容。2.3 为什么少一个文件都连不上再强调一次,两个DLL的分工是各司其职的:dbxopenmysql50.dll在Delphi这边,libmysql.dll在MySQL那边。驱动加载libmysql.dll时按Windows标准DLL搜索顺序找文件:exe所在目录、系统System32目录、环境变量PATH里的路径。只放dbxopenmysql50.dll,Delphi能正常加载驱动,掉进去mysql.dll时直接报126错误(找不到指定模块)。只放libmysql.dll,dbExpress报Cannot Load DBX Driver,因为它没找到驱动文件。两者必须同时存在,且放在程序能搜到的位置。3. 部署与配置:35行代码让Delphi程序直连MySQL 5.73.1 DLL放哪里最省心我在这份资源的落地部署中,一律采用exe同目录方案。打开工程输出目录,确认exe编译到哪里,就把dbxopenmysql50.dll和libmysql.dll复制进去。发布时这三个文件一起打包,客户端解压即可运行,不依赖安装程序修改系统目录,也不怕杀毒软件拦System32下的DLL写入。如果你还在IDE里调试,要注意一个问题:32位Delphi程序在64位Windows上运行时,System32目录会被系统重定向到SysWOW64。把DLL手工复制到C:\Windows\System32,看起来在,程序实际搜到的可能是另一个路径。这个坑我后面还会单独讲。3.2 连接参数配置代码下面是核心连接代码。我第一次配置成功时只改动了这一段,没有碰任何业务代码。function ConnectMySQL57(AConn: TSQLConnection): Boolean; begin Result := False; // 指定驱动DLL与客户端DLL的路径 AConn.DriverName := 'MYSQL50'; AConn.LibraryName := 'dbxopenmysql50.dll'; AConn.VendorLib := ExtractFilePath(Application.ExeName) + 'libmysql.dll'; // 连接参数集中写在Params里,不要依赖IDE的连接定义文件 with AConn.Params do begin Values['HostName'] := '127.0.0.1'; Values['Port'] := '3306'; Values['Database'] := 'old_system'; Values['User_Name'] := 'root'; Values['Password'] := 'your_password'; Values['BlobSize'] := '1024'; // 按需开启字符集设置,保持与库表一致 Values['ServerCharSet'] := 'utf8mb4'; end; try AConn.Connected := True; Result := True; except on E: Exception do begin // 这里不要吞异常,至少记录 E.Message 和 AConn.DbxErrorCode OutputDebugString(PChar('connect failed: ' + E.Message)); end; end; end;这段代码的逻辑很简单:先指定驱动名和两个DLL的路径,再写入连接参数,最后尝试打开连接。重点在第3行到第5行——DriverName、LibraryName、VendorLib三者是配套的。DriverName填的是“MYSQL50”,意思是让dbExpress框架知道该加载哪种驱动。注意不同版本的Delphi中这个名字可能略有差异,有的是“MYSQL”,有的是“MYSQL50”,还有的是“tmysql50”。我一般先看Delphi安装目录下的dbxdrivers.ini里注册过的名称再填,避免IDE与代码里写的不一致。HostName我建议填127.0.0.1而不是localhost。Windows下delphi的dbExpress对localhost有时会触发IPv6解析,出现连接超时的诡异问题,换IP直连就秒开。General库里也有这种情况,这算是我长期调dbExpress总结的经验。ServerCharSet值设为utf8mb4后,如果服务端默认字符集也是utf8mb4,中文存取都没问题。MySQL 5.7默认字符集是utf8mb4的居多,但如果是老库升级上来的,可能还是utf8mb3,这时需要根据实际库来改。3.3 参数选择说明上面代码里几个主要参数,按我项目里的使用经验整理如下:参数示例值说明注意点DriverNameMYSQL50dbExpress驱动名与dbxdrivers.ini里注册名保持一致LibraryNamedbxopenmysql50.dlldbExpress驱动动态库放在exe同目录即可VendorLiblibmysql.dllMySQL官方客户端库必须与exe位宽一致HostName127.0.0.1服务器地址避免用localhostPort3306MySQL服务端口5.7默认3306Databaseold_system数据库名提前创建并赋予权限User_Nameroot登录用户建议创建专用账号Passwordyour_password登录密码5.7支持mysql_native_passwordServerCharSetutf8mb4连接字符集与库表字符集匹配BlobSize1024大字段预读大小字段大就调高参数清单里最容易忽略的是BlobSize。老项目里存有图片或文档BLOB数据时,如果BlobSize设置太小,读取大字段会频繁分片,表现就是界面卡顿。我一般设到1MB以上,具体数值看库中最大记录。再说一下为什么不推荐依赖IDE里的Connection定义。开发机上调试很顺,换到客户机器后,IDE的连接定义文件、注册表没有带过去,程序启动就会报找不到连接。把连接代码写死在程序里,发布包就只有exe加两个DLL,不会出现环境依赖问题。这个习惯我给新接手的同事也反复强调。3.4 发布形态与文件清单最终交付的应用目录应该是这样:你的应用.exe dbxopenmysql50.dll libmysql.dll就这三个文件,没有别的隐藏依赖。dbxopenmysql50.dll不需要安装到Windows目录,libmysql.dll也不需要MySQL客户端安装包。我曾经把整个客户端的MySQL安装包一起带过去,后来发现完全是多余的,反而因为版本冲突在客户机器上闹出两次蓝屏——其实那两次都是杀毒软件拦截DLL注入,但至少证明包容越简单越不容易出错。4. 避坑指南:MySQL 5.7连接失败时的五个高频故障4.1 启动即报“Cannot load dbxopenmysql50.dll”或者“Cannot Load DBX Driver”这个现象最容易出现在刚把工程迁移到新机器的时候。程序一启动,还没走到窗体显示就直接弹错误框,或者IDE里连TSQLConnection的Connected属性都勾不上。原因大致有两个:一是dbxopenmysql50.dll不在搜索路径里;二是驱动文件与Delphi编译的bitness不匹配。32位Delphi编译出来的程序加载64位DLL,Windows根本不给你加载机会。解决办法:先把两个DLL复制到exe同目录,确认文件不是0字节。然后在代码里用LibraryName属性显式指定驱动文件名,让dbExpress框架去exe目录找。如果还报这个错,下载一个DLL位宽查看工具看一眼,程序是32位就配32位库,是64位就配64位库。4.2 错误码126或127:LoadLibrary失败这个错通常更隐蔽。程序没有说“找不到驱动”,而是说“找不到指定的模块”或“指定的程序要求新的Windows版本”。126是找不到依赖模块,127是找不到入口点。原因要挖两层。第一层是libmysql.dll本身缺失,程序加载dbxopenmysql50.dll时,驱动内部又要加载libmysql.dll,这个依赖过程失败就会报126。第二层是libmysql.dll依赖了更高版本的VC运行库,目标机器没有装,错误码同样显示126甚至是0xc000007b。解决办法:先把libmysql.dll补上,再装一次VC运行库合集。这个坑我栽得最冤,有一次客户机器报126,我把DLL反复复制了十几遍都没效果,最后发现是客户机器没有安装VC++ 2015运行库。dbxopenmysql50.dll和libmysql.dll都是微软编译器生成的,底层依赖运行库是老规矩。4.3 连接报握手失败:Client does not support authentication protocol这个错误不是在驱动层报出来的,而是在MySQL服务端报的。程序连接时,服务端返回一条英文错误,大意是“客户端不支持服务端请求的认证协议,请升级MySQL客户端”。原因很直接:MySQL账号的认证插件不是mysql_native_password,而是caching_sha2_password。MySQL 5.7大部分默认情况下还是用native_password,但如果数据库是从MySQL 8.0降级迁移回来的,或者DBA手工改过认证插件,就会撞上这个问题。dbxopenmysql50.dll对应的libmysql.dll是早期Connector/C的产物,不认识caching_sha2_password的握手流程。解决办法是把账号的认证插件改回native_password:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;执行完这条SQL再连就通了。我一般建议项目里固定一个专用账号,把认证插件写进初始化脚本,不要用root裸奔,免得哪次DBA整改密码策略又把插件改了,程序毫无征兆地连不上。4.4 64位libmysql配32位exe,启动连上又闪退这种故障最有迷惑性,因为程序能正常启动,连接也能建立,但一执行查询就崩,或者窗体刚出来就闪退,看事件日志是“应用程序错误”。我最早还以为是驱动不稳定,浪费了整整半天。原因就是位宽不匹配。64位MySQL安装包自带的libmysql.dll是64位版本,32位Delphi程序加载它也能加载成功,但内存布局不一样,调用返回值时直接错乱。表现起来就是在某些函数调用点上随机崩溃。解决办法:把libmysql.dll换成32位版本。最简单的方法是从MySQL官方Connector/C的32位安装包取出libmysql.dll,或者直接下载我用的这份资源,它里面配好的就是32位libmysql.dll,省得去官网翻。Delphi XE之类的老IDE默认编译32位exe,取库文件时盯紧bitness就行。4.5 连接成功但数据不对:中文乱码与时区差8小时这几个问题不属于连不上,而是连上后数据不对,最容易让业务方误判成程序bug。典型表现是查询出的中文全是问号,或者数据库里存的时间值读出来和本地时间差8小时。中文乱码的根源是连接字符集没有协商。数据库表是utf8mb4,但连接用的字符集是latin1,两边转换时丢了字。解决办法是在Params里加上ServerCharSet=utf8mb4,或者在OnAfterConnect事件里执行SET NAMES utf8mb4。我那条配置代码里已经写了ServerCharSet。时区问题则是MySQL 5.7与Delphi之间互传DATETIME时用了服务端时区设置。MySQL的my.ini里如果没有显式设置default-time-zone,用的就是操作系统时区。我在国内机器上一般不会遇到8小时偏差,但客户服务器放在海外机房时就翻车过。解决思路是在连接成功后执行一句话时区SQL。SET time_zone = '+08:00';这个语句适合放在TSQLConnection的AfterConnect事件里执行。要注意顺序,不能提前到Params里配置,dbExpress没有暴露timezone参数。5. 验证与进阶:用一个小工具确认libmysql.dll版本与连通性5.1 先确认客户端库版本再连库拿到资源后,别急着往项目里塞,先做一个20行的验证工具,确认libmysql.dll的客户端版本。MySQL C API里有个mysql_get_client_version函数,可以在Delphi里静态或动态调用。我一般写个小的控制台程序,在连接之前就把它打出来,确认是不是5.7配套版本。program CheckMysqlClient; {$APPTYPE CONSOLE} uses SysUtils, Windows; var hLib: THandle; GetVer: function: LongWord; cdecl; begin hLib := LoadLibrary('libmysql.dll'); if hLib = 0 then begin Writeln('load libmysql.dll failed, error code: ', GetLastError); Halt(1); end; @GetVer := GetProcAddress(hLib, 'mysql_get_client_version'); if Assigned(GetVer) then Writeln('mysql client version: ', GetVer div 100, '.', (GetVer div 100) mod 100, '.', GetVer mod 100) else Writeln('mysql_get_client_version entry point not found'); FreeLibrary(hLib); end.这个程序直接LoadLibrary加载libmysql.dll,然后取mysql_get_client_version这个导出函数,调用后换算成x.y.z格式打出来。如果打印出的版本是5.x或6.x,说明客户端库是对的。如果连LoadLibrary都失败,说明依赖的VC运行库缺失,先补运行库再说。5.2 连接验证的回归清单我每部署一台新客户机器,都会按固定清单快速过一遍,几十秒就能判断环境有没有问题。检查项验证方法预期结果两个DLL存在查看exe目录文件列表都存在且非0字节DLL位宽一致用工具查看DLL bitness与exe同位数客户端库可加载运行上面小工具打印5.x或6.x版本号网络端口通telnet其IP 3306能连通或收到响应认证插件正确查询mysql.user表plugin字段值为mysql_native_password字符集匹配连接后执行SHOW VARIABLES LIKE 'character%'utf8mb4族其中查询用户认证插件的SQL是:SELECT user, host, plugin FROM mysql.user;5.3 进阶:这个资源组合在升级MySQL 8.0时还能用吗这个问题的答案很关键。MySQL 8.0的默认认证插件切到了caching_sha2_password,老libmysql.dll基本连不上8.0。两份DLL的组合极限就在MySQL 5.7,这是老项目数据要做下一步升级时必须预留的边界。如果业务方来问能不能直接升级到8.0,我会明确说老驱动架构不支持,要么换FireDAC新驱动,要么先在服务端把认证插件全改成mysql_native_password再过渡。顺便提一个经验:我每次给老项目做完这类兼容性修复,都要把验证小工具和连接参数说明放进项目doc目录。三个月后再有人接手,不至于把这两个DLL当成垃圾文件清掉,也不至于乱改ServerCharSet导致全库中文乱码。从那以后我再部署任何Delphi连MySQL的环境,都会强制走一遍验证清单,看清楚DLL位宽和插件类型才交付,这一步省下了无数远程排查的时间。希望帮到你。本文还有配套的精品资源,点击获取
简介:一套针对Delphi 7通过dbExpress连接MySQL 5.7的可用动态库包,专为解决网上常见驱动缺失、连接失败问题而整理,适合使用老版本Delphi开发数据库应用、需要升级或迁移MySQL环境的开发者。压缩包共17个文件,包含dll动态库、可执行测试用例、SQL脚本、工程源码(pas/dfm/dpr)及配置说明文档等,包体仅1.3MB,便于快速部署。其中libmysql.dll与dbxopenmysql50.dll已通过作者项目实测,并附带演示如何区分数据库字段的空值与空字符串,避免常见判断误区。程序可在Windows XP与Windows 10下运行,发布时只需携带两个dll及midas库。已有826人学习下载,适合直接复用或参考实现细节。1. Delphi老项目连不上MySQL 5.7:一份动态库资源解了燃眉之急如果你还在维护Delphi老系统,大概率撞过这堵墙:服务端数据库从MySQL 5.0升到5.7,客户端程序没动,TSQLConnection连上去直接报“Cannot Load DBX Driver”或者打开后闪退。我接手的老项目就栽在这上面,折腾一整天,最后发现解法朴实到不敢相信——把libmysql.dll和dbxopenmysql50.dll两个动态库放到程序exe同目录,dbExpress就能正常走MySQL 5.7的协议。这篇文章把这段踩坑过程完整拆开:两个DLL各管什么、怎么部署、连接参数怎么定、哪些坑必踩。适合正在用dbExpress连MySQL 5.7的老项目维护者,也适合刚做完数据库升级、客户端还没适配的团队。2. 两个DLL的分工:从MySQL 5.0到5.7的dbExpress兼容方案2.1 dbExpress驱动链路:应用程序到底需要几层库dbExpress是Delphi早期的跨数据库访问层,它本身不是一个连接程序,而是一套框架。你在窗体上拖一个TSQLConnection,设置好DriverName,剩下的脏活全由框架转给底层的厂家驱动。不同数据库对应不同的驱动动态库,MySQL这边就是dbxopenmysql50.dll。把这条链路记住,后面所有排查都靠它:Delphi应用 ↓ TSQLConnection组件 dbxopenmysql50.dll (dbExpress驱动) ↓ MySQL C API调用 libmysql.dll (MySQL客户端连接库) ↓ TCP 3306 MySQL Server 5.7dbxopenmysql50.dll负责把dbExpress的调用转换成MySQL C API函数调用,例如mysql_init、mysql_real_connect、mysql_query等。但C API这些函数的实体并不在这个驱动里,而在MySQL官方提供的libmysql.dll中。换句话说,驱动文件只负责翻译,网络协议真正干活的是客户端库。所以缺了任何一个文件,整条链路都断。我见过不少人在第一步就搞错,把dbxopenmysql50.dll当成万能钥匙,连上后提示Invalid vendor library或LoadLibrary失败,然后开始怀疑版本。其实只要链路图在脑子里,这类报错扫一眼就知道是缺了libmysql.dll。2.2 MySQL 5.7为什么能沿用5.0的驱动第一次拿到这份资源的人都会有同样的疑问:文件名里的“openmysql50”明显是给MySQL 5.0用的,接5.7真的行?实测下来是可行的,这背后有技术原因。MySQL C API的公开接口从5.0到5.7没有破坏性变更。驱动里调用的mysql_real_connect、mysql_query、mysql_store_result这些老牌函数,在5.7的libmysql.dll里依然原样导出。dbExpress驱动本身不关心MySQL服务端的小版本号,它只按C API标准函数签名去加载libmysql.dll的导出表。只要libmysql.dll换成5.7配套编译的那一版,驱动文件本身不动,就能连上5.7的服务端。也有人换过FireDAC或第三方组件来绕开dbExpress链路。不是不行,但老项目里的TSQLQuery、TSQLStoredProc、TDataSetProvider一堆组件全要改,数据字典、字段类型映射也要重新调。我评估过,改动量太大,远不如保留dbExpress架构、只换libmysql.dll划算。这份资源的价值正在于,它能让你一行业务代码不改就完成MySQL版本兼容。2.3 为什么少一个文件都连不上再强调一次,两个DLL的分工是各司其职的:dbxopenmysql50.dll在Delphi这边,libmysql.dll在MySQL那边。驱动加载libmysql.dll时按Windows标准DLL搜索顺序找文件:exe所在目录、系统System32目录、环境变量PATH里的路径。只放dbxopenmysql50.dll,Delphi能正常加载驱动,掉进去mysql.dll时直接报126错误(找不到指定模块)。只放libmysql.dll,dbExpress报Cannot Load DBX Driver,因为它没找到驱动文件。两者必须同时存在,且放在程序能搜到的位置。3. 部署与配置:35行代码让Delphi程序直连MySQL 5.73.1 DLL放哪里最省心我在这份资源的落地部署中,一律采用exe同目录方案。打开工程输出目录,确认exe编译到哪里,就把dbxopenmysql50.dll和libmysql.dll复制进去。发布时这三个文件一起打包,客户端解压即可运行,不依赖安装程序修改系统目录,也不怕杀毒软件拦System32下的DLL写入。如果你还在IDE里调试,要注意一个问题:32位Delphi程序在64位Windows上运行时,System32目录会被系统重定向到SysWOW64。把DLL手工复制到C:\Windows\System32,看起来在,程序实际搜到的可能是另一个路径。这个坑我后面还会单独讲。3.2 连接参数配置代码下面是核心连接代码。我第一次配置成功时只改动了这一段,没有碰任何业务代码。function ConnectMySQL57(AConn: TSQLConnection): Boolean; begin Result := False; // 指定驱动DLL与客户端DLL的路径 AConn.DriverName := 'MYSQL50'; AConn.LibraryName := 'dbxopenmysql50.dll'; AConn.VendorLib := ExtractFilePath(Application.ExeName) + 'libmysql.dll'; // 连接参数集中写在Params里,不要依赖IDE的连接定义文件 with AConn.Params do begin Values['HostName'] := '127.0.0.1'; Values['Port'] := '3306'; Values['Database'] := 'old_system'; Values['User_Name'] := 'root'; Values['Password'] := 'your_password'; Values['BlobSize'] := '1024'; // 按需开启字符集设置,保持与库表一致 Values['ServerCharSet'] := 'utf8mb4'; end; try AConn.Connected := True; Result := True; except on E: Exception do begin // 这里不要吞异常,至少记录 E.Message 和 AConn.DbxErrorCode OutputDebugString(PChar('connect failed: ' + E.Message)); end; end; end;这段代码的逻辑很简单:先指定驱动名和两个DLL的路径,再写入连接参数,最后尝试打开连接。重点在第3行到第5行——DriverName、LibraryName、VendorLib三者是配套的。DriverName填的是“MYSQL50”,意思是让dbExpress框架知道该加载哪种驱动。注意不同版本的Delphi中这个名字可能略有差异,有的是“MYSQL”,有的是“MYSQL50”,还有的是“tmysql50”。我一般先看Delphi安装目录下的dbxdrivers.ini里注册过的名称再填,避免IDE与代码里写的不一致。HostName我建议填127.0.0.1而不是localhost。Windows下delphi的dbExpress对localhost有时会触发IPv6解析,出现连接超时的诡异问题,换IP直连就秒开。General库里也有这种情况,这算是我长期调dbExpress总结的经验。ServerCharSet值设为utf8mb4后,如果服务端默认字符集也是utf8mb4,中文存取都没问题。MySQL 5.7默认字符集是utf8mb4的居多,但如果是老库升级上来的,可能还是utf8mb3,这时需要根据实际库来改。3.3 参数选择说明上面代码里几个主要参数,按我项目里的使用经验整理如下:参数示例值说明注意点DriverNameMYSQL50dbExpress驱动名与dbxdrivers.ini里注册名保持一致LibraryNamedbxopenmysql50.dlldbExpress驱动动态库放在exe同目录即可VendorLiblibmysql.dllMySQL官方客户端库必须与exe位宽一致HostName127.0.0.1服务器地址避免用localhostPort3306MySQL服务端口5.7默认3306Databaseold_system数据库名提前创建并赋予权限User_Nameroot登录用户建议创建专用账号Passwordyour_password登录密码5.7支持mysql_native_passwordServerCharSetutf8mb4连接字符集与库表字符集匹配BlobSize1024大字段预读大小字段大就调高参数清单里最容易忽略的是BlobSize。老项目里存有图片或文档BLOB数据时,如果BlobSize设置太小,读取大字段会频繁分片,表现就是界面卡顿。我一般设到1MB以上,具体数值看库中最大记录。再说一下为什么不推荐依赖IDE里的Connection定义。开发机上调试很顺,换到客户机器后,IDE的连接定义文件、注册表没有带过去,程序启动就会报找不到连接。把连接代码写死在程序里,发布包就只有exe加两个DLL,不会出现环境依赖问题。这个习惯我给新接手的同事也反复强调。3.4 发布形态与文件清单最终交付的应用目录应该是这样:你的应用.exe dbxopenmysql50.dll libmysql.dll就这三个文件,没有别的隐藏依赖。dbxopenmysql50.dll不需要安装到Windows目录,libmysql.dll也不需要MySQL客户端安装包。我曾经把整个客户端的MySQL安装包一起带过去,后来发现完全是多余的,反而因为版本冲突在客户机器上闹出两次蓝屏——其实那两次都是杀毒软件拦截DLL注入,但至少证明包容越简单越不容易出错。4. 避坑指南:MySQL 5.7连接失败时的五个高频故障4.1 启动即报“Cannot load dbxopenmysql50.dll”或者“Cannot Load DBX Driver”这个现象最容易出现在刚把工程迁移到新机器的时候。程序一启动,还没走到窗体显示就直接弹错误框,或者IDE里连TSQLConnection的Connected属性都勾不上。原因大致有两个:一是dbxopenmysql50.dll不在搜索路径里;二是驱动文件与Delphi编译的bitness不匹配。32位Delphi编译出来的程序加载64位DLL,Windows根本不给你加载机会。解决办法:先把两个DLL复制到exe同目录,确认文件不是0字节。然后在代码里用LibraryName属性显式指定驱动文件名,让dbExpress框架去exe目录找。如果还报这个错,下载一个DLL位宽查看工具看一眼,程序是32位就配32位库,是64位就配64位库。4.2 错误码126或127:LoadLibrary失败这个错通常更隐蔽。程序没有说“找不到驱动”,而是说“找不到指定的模块”或“指定的程序要求新的Windows版本”。126是找不到依赖模块,127是找不到入口点。原因要挖两层。第一层是libmysql.dll本身缺失,程序加载dbxopenmysql50.dll时,驱动内部又要加载libmysql.dll,这个依赖过程失败就会报126。第二层是libmysql.dll依赖了更高版本的VC运行库,目标机器没有装,错误码同样显示126甚至是0xc000007b。解决办法:先把libmysql.dll补上,再装一次VC运行库合集。这个坑我栽得最冤,有一次客户机器报126,我把DLL反复复制了十几遍都没效果,最后发现是客户机器没有安装VC++ 2015运行库。dbxopenmysql50.dll和libmysql.dll都是微软编译器生成的,底层依赖运行库是老规矩。4.3 连接报握手失败:Client does not support authentication protocol这个错误不是在驱动层报出来的,而是在MySQL服务端报的。程序连接时,服务端返回一条英文错误,大意是“客户端不支持服务端请求的认证协议,请升级MySQL客户端”。原因很直接:MySQL账号的认证插件不是mysql_native_password,而是caching_sha2_password。MySQL 5.7大部分默认情况下还是用native_password,但如果数据库是从MySQL 8.0降级迁移回来的,或者DBA手工改过认证插件,就会撞上这个问题。dbxopenmysql50.dll对应的libmysql.dll是早期Connector/C的产物,不认识caching_sha2_password的握手流程。解决办法是把账号的认证插件改回native_password:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;执行完这条SQL再连就通了。我一般建议项目里固定一个专用账号,把认证插件写进初始化脚本,不要用root裸奔,免得哪次DBA整改密码策略又把插件改了,程序毫无征兆地连不上。4.4 64位libmysql配32位exe,启动连上又闪退这种故障最有迷惑性,因为程序能正常启动,连接也能建立,但一执行查询就崩,或者窗体刚出来就闪退,看事件日志是“应用程序错误”。我最早还以为是驱动不稳定,浪费了整整半天。原因就是位宽不匹配。64位MySQL安装包自带的libmysql.dll是64位版本,32位Delphi程序加载它也能加载成功,但内存布局不一样,调用返回值时直接错乱。表现起来就是在某些函数调用点上随机崩溃。解决办法:把libmysql.dll换成32位版本。最简单的方法是从MySQL官方Connector/C的32位安装包取出libmysql.dll,或者直接下载我用的这份资源,它里面配好的就是32位libmysql.dll,省得去官网翻。Delphi XE之类的老IDE默认编译32位exe,取库文件时盯紧bitness就行。4.5 连接成功但数据不对:中文乱码与时区差8小时这几个问题不属于连不上,而是连上后数据不对,最容易让业务方误判成程序bug。典型表现是查询出的中文全是问号,或者数据库里存的时间值读出来和本地时间差8小时。中文乱码的根源是连接字符集没有协商。数据库表是utf8mb4,但连接用的字符集是latin1,两边转换时丢了字。解决办法是在Params里加上ServerCharSet=utf8mb4,或者在OnAfterConnect事件里执行SET NAMES utf8mb4。我那条配置代码里已经写了ServerCharSet。时区问题则是MySQL 5.7与Delphi之间互传DATETIME时用了服务端时区设置。MySQL的my.ini里如果没有显式设置default-time-zone,用的就是操作系统时区。我在国内机器上一般不会遇到8小时偏差,但客户服务器放在海外机房时就翻车过。解决思路是在连接成功后执行一句话时区SQL。SET time_zone = '+08:00';这个语句适合放在TSQLConnection的AfterConnect事件里执行。要注意顺序,不能提前到Params里配置,dbExpress没有暴露timezone参数。5. 验证与进阶:用一个小工具确认libmysql.dll版本与连通性5.1 先确认客户端库版本再连库拿到资源后,别急着往项目里塞,先做一个20行的验证工具,确认libmysql.dll的客户端版本。MySQL C API里有个mysql_get_client_version函数,可以在Delphi里静态或动态调用。我一般写个小的控制台程序,在连接之前就把它打出来,确认是不是5.7配套版本。program CheckMysqlClient; {$APPTYPE CONSOLE} uses SysUtils, Windows; var hLib: THandle; GetVer: function: LongWord; cdecl; begin hLib := LoadLibrary('libmysql.dll'); if hLib = 0 then begin Writeln('load libmysql.dll failed, error code: ', GetLastError); Halt(1); end; @GetVer := GetProcAddress(hLib, 'mysql_get_client_version'); if Assigned(GetVer) then Writeln('mysql client version: ', GetVer div 100, '.', (GetVer div 100) mod 100, '.', GetVer mod 100) else Writeln('mysql_get_client_version entry point not found'); FreeLibrary(hLib); end.这个程序直接LoadLibrary加载libmysql.dll,然后取mysql_get_client_version这个导出函数,调用后换算成x.y.z格式打出来。如果打印出的版本是5.x或6.x,说明客户端库是对的。如果连LoadLibrary都失败,说明依赖的VC运行库缺失,先补运行库再说。5.2 连接验证的回归清单我每部署一台新客户机器,都会按固定清单快速过一遍,几十秒就能判断环境有没有问题。检查项验证方法预期结果两个DLL存在查看exe目录文件列表都存在且非0字节DLL位宽一致用工具查看DLL bitness与exe同位数客户端库可加载运行上面小工具打印5.x或6.x版本号网络端口通telnet其IP 3306能连通或收到响应认证插件正确查询mysql.user表plugin字段值为mysql_native_password字符集匹配连接后执行SHOW VARIABLES LIKE 'character%'utf8mb4族其中查询用户认证插件的SQL是:SELECT user, host, plugin FROM mysql.user;5.3 进阶:这个资源组合在升级MySQL 8.0时还能用吗这个问题的答案很关键。MySQL 8.0的默认认证插件切到了caching_sha2_password,老libmysql.dll基本连不上8.0。两份DLL的组合极限就在MySQL 5.7,这是老项目数据要做下一步升级时必须预留的边界。如果业务方来问能不能直接升级到8.0,我会明确说老驱动架构不支持,要么换FireDAC新驱动,要么先在服务端把认证插件全改成mysql_native_password再过渡。顺便提一个经验:我每次给老项目做完这类兼容性修复,都要把验证小工具和连接参数说明放进项目doc目录。三个月后再有人接手,不至于把这两个DLL当成垃圾文件清掉,也不至于乱改ServerCharSet导致全库中文乱码。从那以后我再部署任何Delphi连MySQL的环境,都会强制走一遍验证清单,看清楚DLL位宽和插件类型才交付,这一步省下了无数远程排查的时间。希望帮到你。本文还有配套的精品资源,点击获取