前言 本文将介绍 C++ 如何使用 MySQL Connector/C++ 的 API 连接 MySQL 数据库,适用于 Windows 系统。
版本说明 软件 版本 默认安装路径 MySQL Connector/C++ 1.1.13 C:\Program Files\MySQL\MySQL Connector C++ 1.1.13 OpenSSL v1.1.1L C:\Program Files\OpenSSL-Win64 boost 1_77_0 C:\Program Files\boost_1_77_0 MySQL Server 5.7.33 C++ 11 Visual Studio 2019 Windows System Win 10
MySQL Connector/C++ 介绍 简介
MySQL Connector/C++ 是一个 MySQL 数据库连接器,包含了 C++ 连接 MySQL 服务器所需的头文件和库文件,可用于开发基于 JDBC 的 C++ 应用程序。
开发优势
与 MySQL 客户端库提供的 C 语言 API 相比,MySQL Connector/C++ 为 C++ 用户提供以下好处:
纯 C++ 开发的便利 支持基于 JDBC 4.0 的 API 支持面向对象的编程范式 减少项目的开发时间 可根据要求获得商业许可证 根据 GPL 获得许可,但 FLOSS 许可除外 分发方式
MySQL Connector/C++ 有二进制文件和源代码分发版,并以特定于平台的打包格式提供:
二进制分发版可用于 Windows、Linux、Unix 和类 Unix 平台 源代码分发版可作为压缩的 tar
文件或 zip
文件提供,并可在任何受支持的平台上使用 源代码存储库使用 Git 存储,可在 GitHub 上获得 与 JDBC 的兼容性
MySQL Connector/C++ 与 JDBC 4.0 API 兼容,没有实现整个 JDBC 4.0 API,但具有以下类:Connection、DatabaseMetaData、Driver、PreparedStatement、ResultSet、ResultSetMetaData、Savepoint、Statement。JDBC 4.0 API 为刚才提到的类定义了大约 450 个方法,MySQL Connector/C++ 实现了其中的大约 80%。
支持的平台和先决条件
对于 MySQL Connector/C++ 1.1.11 及更高版本,商业和社区发行版需要依赖 Visual C++ Redistributable for Visual Studio 2015 才能在 Windows 平台上运行。从 MySQL Connector/C++ 1.1.10 开始,社区(非商业)发行版需要依赖适用于 Visual Studio 2013 的 Visual C++ Redistributable。可在 Microsoft 下载中心 获取 Redistributable 的安装包,并在安装 MySQL Connector/C++ 之前安装它。
要运行带 MySQL Connector/C++ 的应用程序,需要 MySQL 5.6 或更高版本的数据库服务器
要构建带 MySQL Connector/C++ 的应用程序
在 Windows 系统上,需要 Microsoft Visual Studio 2015 要从源代码构建 MySQL Connector/C++ 自身
在 Windows 系统上,需要 Microsoft Visual Studio 2015 Building Connector/C++ 需要 MySQL 5.7(5.7.9 或更高版本)或 MySQL 8.0(8.0.11 或更高版本)的客户端库 准备工作 OpenSSL 安装 安装 OpenSSL 在 OpenSSL 官网 下载 Win64 OpenSSL v1.1.1L
版本的安装包,下载完成后直接安装,每一步安装步骤选择默认选项即可。OpenSSL 默认的安装路径是 C:\Program Files\OpenSSL-Win64
。
VS 项目添加 OpenSSL 的 库文件 OpenSSL 安装完成之后,将其安装目录下的 bin
文件夹中的 libssl-1_1-x64.dll
和 libcrypto-1_1-x64.dll
库文件拷贝到 VS 项目的目录中,如下图所示:
VS 项目引入 OpenSSL 的 头文件 右键项目,选择 属性
,导航到 配置属性
-> C/C++
-> 常规
-> 附加包含目录
,添加 OpenSSL 头文件所在的目录路径(如 C:\Program Files\OpenSSL-Win64\include
),如下图所示:
MySQL Connector/C++ 安装 安装 MySQL Connector/C++ 在 MySQL 官网 上下载 1.1.13
版本的 MySQL Connector/C++,下载完成后直接安装即可。若已经本地已经安装过 MySQL Server,则不再需要手动安装 MySQL Connector/C++,因为默认已经安装过了,但需要留意 MySQL Connector/C++ 与 MySQL 的版本是否匹配 。值得一提的是,MySQL Connector/C++ 支持多个版本共存(同时安装不同的版本),其默认的安装路径为 C:\Program Files\MySQL\Connector.C++ 1.x
。
VS 项目添加 MySQL Connector/C++ 的 库文件 MySQL Connector/C++ 安装完成后,将其安装目录下 lib/opt
文件夹中的 mysqlcppconn.dll
与 mysqlcppconn.lib
库文件拷贝到 VS 项目的目录中,如下图所示:
VS 项目引入 MySQL Connector/C++ 的头文件 右键项目,选择 属性
,导航到 配置属性
-> C/C++
-> 常规
-> 附加包含目录
,添加 MySQL Connector/C++ 头文件所在的目录路径(如 C:\Program Files\MySQL\MySQL Connector C++ 1.1.13\include
),如下图所示:
C++ 连接 MySQL 的实战案例 MySQL 数据库初始化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 DROP DATABASE IF EXISTS `t_shop`;CREATE DATABASE `t_shop` DEFAULT CHARACTER SET UTF8;USE `t_shop`; DROP TABLE IF EXISTS `properties`;CREATE TABLE `properties` ( `ID` int (11 ) NOT NULL AUTO_INCREMENT, `KEY` varchar (200 ) DEFAULT NULL , `VALUE ` varchar (200 ) DEFAULT NULL , `REMARK` varchar (200 ) DEFAULT NULL , PRIMARY KEY (`ID`) USING BTREE, UNIQUE KEY `key_unique_index` (`KEY`) ) ENGINE= InnoDB AUTO_INCREMENT= 27 DEFAULT CHARSET= UTF8 ROW_FORMAT= DYNAMIC ; INSERT INTO `properties` (`KEY`, `VALUE `, `REMARK`) VALUES ('test_limit_price' , '30.5' , '限制价格' );INSERT INTO `properties` (`KEY`, `VALUE `, `REMARK`) VALUES ('test_limit_number' , '430' , '限制数量' );INSERT INTO `properties` (`KEY`, `VALUE `, `REMARK`) VALUES ('test_limit_balance' , '929.32' , '限制余额' );
C++ 连接 MySQL 的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #pragma once #include <vector> #include <iostream> #include <mysql_connection.h> #include <cppconn/driver.h> #include <cppconn/exception.h> #include <cppconn/resultset.h> #include <cppconn/statement.h> #include <cppconn/prepared_statement.h> using namespace std;using namespace sql;class MysqlDB {public : MysqlDB (const string host, const string username, const string password, const string database); ~MysqlDB (); public : bool Execute (const char * sql) ; int ExecuteUpdate (const char * sql) ; unique_ptr<ResultSet> Query (const char * query, const vector<string> parameters) ; private : string host; string username; string password; string database; Driver* driver; unique_ptr<Connection> connection; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 #include "mysqldb.h" MysqlDB::MysqlDB (const string host, const string username, const string password, const string database) { this ->host = host; this ->username = username; this ->password = password; this ->database = database; try { this ->driver = get_driver_instance (); if (!this ->driver) { throw "failed to load mysql driver" ; } this ->connection.reset (driver->connect (this ->host.c_str (), this ->username.c_str (), this ->password.c_str ())); if (!this ->connection) { throw "failed to connect mysql server" ; } else { this ->connection->setSchema (this ->database.c_str ()); } } catch (SQLException& e) { cout << "# ERR: SQLException in " << __FILE__ << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what () << endl; }; } MysqlDB::~MysqlDB () { } bool MysqlDB::Execute (const char * sql) { try { if (this ->connection) { unique_ptr<Statement> statement = nullptr ; statement.reset (this ->connection->createStatement ()); if (statement) { return statement->execute (sql); } } } catch (SQLException& e) { cout << "# ERR: SQLException in " << __FILE__ << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what () << endl; } return false ; } int MysqlDB::ExecuteUpdate (const char * sql) { try { if (this ->connection) { unique_ptr<Statement> statement = nullptr ; statement.reset (this ->connection->createStatement ()); if (statement) { return statement->executeUpdate (sql); } } } catch (SQLException& e) { cout << "# ERR: SQLException in " << __FILE__ << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what () << endl; } return 0 ; } unique_ptr<ResultSet> MysqlDB::Query (const char * sql, const vector<string> parameters) { unique_ptr<ResultSet> resultSet = nullptr ; try { if (this ->connection) { int index = 0 ; unique_ptr<PreparedStatement> statement = nullptr ; statement.reset (this ->connection->prepareStatement (sql)); if (statement) { for (auto iterator = parameters.cbegin (); iterator != parameters.cend (); iterator++) { index++; statement->setString (index, (*iterator).c_str ()); } resultSet.reset (statement->executeQuery ()); } } } catch (SQLException& e) { cout << "# ERR: SQLException in " << __FILE__ << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what () << endl; } return resultSet; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include "mysqldb.h" using namespace std;int main () { unique_ptr<MysqlDB> db (new MysqlDB("tcp://127.0.0.1:3306" , "root" , "123456" , "t_shop" )) ; string querySql = "select * from properties where `KEY` = ?" ; unique_ptr<ResultSet> result = db->Query (querySql.c_str (), { "test_limit_price" }); if (result) { cout << "Query: " << querySql << endl; while (result->next ()) { cout << result->getInt ("ID" ) << " | " ; cout << result->getString ("KEY" ).c_str () << " | " ; cout << result->getString ("VALUE" ).c_str () << " | " ; cout << result->getString ("REMARK" ).c_str () << " | " ; cout << endl; } } return 0 ; }
程序运行输出的结果如下:
1 2 Query: select * from properties where `KEY` = ? 27 | test_limit_price | 30.5 | 限制价格 |
常见问题 缺失 Boost 库 错误信息:
项目执行编译操作后,VS 出现下述错误信息,这是本地缺失 boost
库导致的。1 fatal error C1083: 无法打开包括文件: “boost/shared_ptr.hpp”: No such file or directory
解决方法:
a) 在 Boost 官网 下载最新版本的 Boost
,并解压到本地磁盘,例如解压路径为:C:\Program Files\boost_1_77_0
b) 右键项目,选择 属性
,导航到 配置属性
-> C/C++
-> 常规
-> 附加包含目录
,添加 Boost
的安装路径(如 C:\Program Files\boost_1_77_0
),如下图所示 c) 重新执行项目的编译操作
缺失 libssl-1_1-64.dll 文件 错误信息:
项目运行后,系统弹窗提示以下错误信息。1 由于找不到 libssl-1_1-64.dll,无法继续执行代码。重新安装程序可能会解决此问题。
解决方法:
安装 OpenSSL,并拷贝 libssl-1_1-64.dll
库文件到 VS 项目的目录中,具体步骤可参考上面的 OpenSSL - 安装 教程。 缺失 libcrypto-1_1-x64.dll 文件 错误信息:
项目运行后,系统弹窗提示以下错误信息。1 由于找不到 libcrypto-1_1-x64.dll,无法继续执行代码。重新安装程序可能会解决此问题。
解决方法:
安装 OpenSSL,并拷贝 libcrypto-1_1-x64.dll
库文件到 VS 项目的目录中,具体步骤可参考上面的 OpenSSL - 安装 教程。 参考文档