C++ MySQL 常用接口(基于 MySQL Connector/C++)
1. 數據庫連接
接口:
sql::mysql::MySQL_Driver *driver;
sql::Connection *con;
作用:
用于創建 MySQL 連接對象。
示例:
driver = sql::mysql::get_mysql_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "user", "password");
釋放資源:
delete con;
2. 選擇數據庫
接口:
con->setSchema("database_name");
作用:
指定要操作的數據庫。
示例:
con->setSchema("test_db");
3. 創建 SQL 語句對象
接口:
sql::Statement *stmt;
stmt = con->createStatement();
作用:
創建一個 SQL 語句執行對象。
示例:
stmt = con->createStatement();
stmt->execute("CREATE TABLE IF NOT EXISTS users (id INT, name VARCHAR(50))");
delete stmt;
4. 執行 SQL 語句
接口:
stmt->execute("SQL語句");
stmt->executeQuery("SQL查詢語句");
stmt->executeUpdate("SQL更新語句");
作用:
execute()
用于執行不返回結果集的 SQL 語句(如CREATE TABLE
)。executeQuery()
用于執行SELECT
查詢,返回ResultSet
結果集。executeUpdate()
用于INSERT
、UPDATE
、DELETE
,返回影響的行數。
示例:
stmt = con->createStatement();
stmt->execute("INSERT INTO users (id, name) VALUES (1, 'Tom')");
sql::ResultSet *res = stmt->executeQuery("SELECT * FROM users");
int rows = stmt->executeUpdate("UPDATE users SET name='Jerry' WHERE id=1");delete res;
delete stmt;
5. 獲取查詢結果
接口:
sql::ResultSet *res;
res->next();
res->getInt("column_name");
res->getString("column_name");
作用:
獲取查詢結果,并讀取列值。
示例:
sql::ResultSet *res = stmt->executeQuery("SELECT * FROM users");
while (res->next()) {std::cout << "ID: " << res->getInt("id") << ", Name: " << res->getString("name") << std::endl;
}
delete res;
6. 使用預處理語句
接口:
sql::PreparedStatement *pstmt;
pstmt = con->prepareStatement("SQL語句");
pstmt->setInt(參數索引, 整數值);
pstmt->setString(參數索引, 字符串值);
pstmt->execute();
pstmt->executeQuery();
pstmt->executeUpdate();
作用:
prepareStatement()
預編譯 SQL,提高執行效率并防止 SQL 注入。setInt()
/setString()
設置 SQL 語句中的參數值。
示例:
sql::PreparedStatement *pstmt = con->prepareStatement("INSERT INTO users (id, name) VALUES (?, ?)");
pstmt->setInt(1, 2);
pstmt->setString(2, "Alice");
pstmt->executeUpdate();
delete pstmt;
7. 事務處理
自動提交(Auto Commit)
MySQL 默認啟用 Auto Commit,每條 INSERT
、UPDATE
、DELETE
語句都會 立即生效,即使程序崩潰,數據也已經修改了。
示例(默認自動提交)
sql::Statement *stmt = con->createStatement();
stmt->execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
delete stmt; // 即使程序崩潰,數據庫的修改依然有效
手動事務(關閉自動提交)
如果希望多個 SQL 語句 全部成功或全部失敗,需要 關閉自動提交 并手動 COMMIT
或 ROLLBACK
。
接口:
con->setAutoCommit(false);
con->commit();
con->rollback();
作用:
setAutoCommit(false)
:關閉自動提交,進入事務模式。commit()
:提交事務,所有 SQL 語句的更改生效。rollback()
:回滾事務,撤銷所有未提交的更改。
示例(手動控制事務)
try {con->setAutoCommit(false); // 關閉自動提交,開啟事務模式sql::PreparedStatement *pstmt = con->prepareStatement("UPDATE accounts SET balance = balance - ? WHERE id = ?");pstmt->setDouble(1, 100.0);pstmt->setInt(2, 1);pstmt->executeUpdate();delete pstmt;pstmt = con->prepareStatement("UPDATE accounts SET balance = balance + ? WHERE id = ?");pstmt->setDouble(1, 100.0);pstmt->setInt(2, 2);pstmt->executeUpdate();delete pstmt;con->commit(); // **手動提交事務,所有修改一起生效**
} catch (sql::SQLException &e) {con->rollback(); // **出錯時回滾,保證數據一致性**std::cerr << "Transaction failed: " << e.what() << std::endl;
}
事務的使用場景
適用于需要保證 數據一致性 的情況:
- 銀行轉賬(A 賬戶扣錢,B 賬戶加錢,必須同時成功)
- 庫存管理(購買商品時,需要同時更新庫存和訂單信息)
- 訂單處理(下單時,必須同時修改多個表的數據)
總結
- MySQL 默認
Auto Commit = true
,每條 SQL 語句都會立即提交。 - 關閉
Auto Commit
后,可以 手動提交或回滾,確保數據一致性。 - 使用
commit()
確保更改生效,使用rollback()
處理失敗情況。
8. 關閉連接
接口:
delete res;
delete stmt;
delete pstmt;
delete con;
作用:
釋放資源,避免內存泄漏。
示例:
delete res;
delete stmt;
delete pstmt;
delete con;
總結
類別 | 接口 | 作用 |
---|---|---|
數據庫連接 | sql::mysql::MySQL_Driver *driver; sql::Connection *con; driver = sql::mysql::get_mysql_driver_instance(); con = driver->connect(...); | 連接 MySQL 數據庫 |
選擇數據庫 | con->setSchema("database_name"); | 選擇數據庫 |
執行 SQL | stmt->execute("SQL語句"); stmt->executeQuery("SQL查詢語句"); stmt->executeUpdate("SQL更新語句"); | 執行 SQL 語句 |
獲取查詢結果 | res->next(); res->getInt("column_name"); res->getString("column_name"); | 獲取查詢結果 |
預處理語句 | pstmt = con->prepareStatement("SQL語句"); pstmt->setInt(1, value); pstmt->setString(2, "value"); pstmt->executeUpdate(); | 預編譯 SQL,防止 SQL 注入 |
事務管理 | con->setAutoCommit(false); con->commit(); con->rollback(); | 控制事務提交和回滾 |
釋放資源 | delete res; delete stmt; delete pstmt; delete con; | 釋放內存,避免泄漏 |
代碼示例
/* Copyright 2008, 2010, Oracle and/or its affiliates.This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.There are special exceptions to the terms and conditions of the GPL
as it is applied to this software. View the full text of the
exception in file EXCEPTIONS-CONNECTOR-C++ in the directory of this
software distribution.This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*//* Standard C++ includes */
#include <stdlib.h>
#include <iostream>/*Include directly the differentheaders from cppconn/ and mysql_driver.h + mysql_util.h(and mysql_connection.h). This will reduce your build time!
*/
#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;int main(void)
{
cout << endl;
cout << "Let's have MySQL count from 10 to 1..." << endl;try {sql::Driver *driver;sql::Connection *con;sql::Statement *stmt;sql::ResultSet *res;sql::PreparedStatement *pstmt;/* Create a connection */driver = get_driver_instance();con = driver->connect("tcp://127.0.0.1:3306", "root", "root");/* Connect to the MySQL test database */con->setSchema("test");stmt = con->createStatement();stmt->execute("DROP TABLE IF EXISTS test");stmt->execute("CREATE TABLE test(id INT)");delete stmt;/* '?' is the supported placeholder syntax */pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)");for (int i = 1; i <= 10; i++) {pstmt->setInt(1, i);pstmt->executeUpdate();}delete pstmt;/* Select in ascending order */pstmt = con->prepareStatement("SELECT id FROM test ORDER BY id ASC");res = pstmt->executeQuery();/* Fetch in reverse = descending order! */res->afterLast();while (res->previous())cout << "\t... MySQL counts: " << res->getInt("id") << endl;delete res;delete pstmt;delete con;} catch (sql::SQLException &e) {cout << "# ERR: SQLException in " << __FILE__;cout << "(" << __FUNCTION__ << ") on line " ?<< __LINE__ << endl;cout << "# ERR: " << e.what();cout << " (MySQL error code: " << e.getErrorCode();cout << ", SQLState: " << e.getSQLState() << ?" )" << endl;
}cout << endl;return EXIT_SUCCESS;
}