使用 mysql Connector/c++ 前必须确认:①已安装对应平台的 libmysqlclient 或 libmysql.dll 且路径正确;②使用官方 mysql-connector-c++ ≥8.0.33 版本以支持 caching_sha2_password;③编译时显式链接 -lmysqlcppconn(linux/macos)或 mysqlcppconn.lib(windows)。

用 MySQL Connector/C++ 连接数据库前必须确认的三件事
直接上手写 sql::Driver::getMySQLDriverInstance() 却报错?大概率卡在这三个前提没满足:
• 你的系统已安装 libmysqlclient(Linux/macOS)或 libmysql.dll(Windows),且动态链接路径正确;
• 你链接的是官方 mysql-connector-c++(不是旧版 mysql++ 或 OTL),版本建议 ≥8.0.33,否则不支持 MySQL 8 默认的 caching_sha2_password 认证插件;
• CMake 或编译命令里显式链接了 -lmysqlcppconn(Linux/macOS)或正确配置了 Windows 的 mysqlcppconn.lib 导入库。
最简可运行连接代码(含异常处理)
别抄网上裸调 driver->connect() 的例子——实际项目中必须捕获 sql::SQLException,否则连接失败会直接 crash。下面这段能跑通、能提示具体错误原因:
#include #include #include int main() { try { sql::mysql::MySQL_Driver *driver = sql::mysql::get_mysql_driver_instance(); std::unique_ptr conn( driver->connect("tcp://127.0.0.1:3306", "root", "password") ); conn->setSchema("testdb"); std::cout << "Connected successfully.n"; } catch (const sql::SQLException &e) { std::cerr << "SQL Error: " << e.what() << "n"; std::cerr << "MySQL Error Code: " << e.getErrorCode() << "n"; std::cerr << "SQL State: " << e.getSQLState() << "n"; } }
注意:MySQL 8+ 默认拒绝空密码和 root 远程登录,本地测试请先执行 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; 切换认证方式。
executeQuery() 和 executeUpdate() 别混用
查数据用 executeQuery(),增删改用 executeUpdate()——这不是风格问题,是类型安全强制要求。前者返回 sql::ResultSet*,后者返回影响行数 int64_t。若用 executeQuery("INSERT ..."),运行时报错是 Could not retrieve result set from statement,而不是语法错误提示。
立即学习“C++免费学习笔记(深入)”;
-
select、SHOW、EXPLAIN→ 必须用executeQuery() -
INSERT、UPDATE、delete、DROP、CREATE→ 必须用executeUpdate() - 带参数的预处理语句要用
sql::PreparedStatement,不能拼字符串,否则 SQL 注入风险极高
连接池不是默认开启的,得自己管生命周期
官方 Connector/C++ 不提供内置连接池。每次 new Connection 都是真实 TCP 连接,频繁创建销毁开销大。常见做法是:
• 用静态 std::shared_ptr<:connection> 管理单例连接(适合低并发 CLI 工具);
• 高并发场景下,用 std::queue<:unique_ptr>> 手写简易池,配合 conn->close() 归还(注意:调用 close() 后指针失效,不能再用);
• 更稳妥的方式是改用 libpqxx(postgresql)或 soci(多后端抽象),它们原生支持连接池。
MySQL 官方 connector 对异步操作、ssl 配置、超时控制都藏在 sql::ConnectOptionsMap 里,但文档极简——比如设置连接超时要传 options["OPT_CONNECT_TIMEOUT"] = 5,不写这行,底层 TCP 超时可能是分钟级,线上故障排查时容易误判为数据库挂了。