Phân trang kết quả truy vấn MySQL bằng C++
Hướng dẫn chi tiết cách phân trang kết quả truy vấn MySQL bằng C++ với Prepared Statements. Bài viết giúp bạn hiểu cách truy vấn dữ liệu và phân trang hiệu quả trong C++ khi làm việc với MySQL.
Trong bài viết này, chúng ta sẽ tìm hiểu cách phân trang kết quả truy vấn từ MySQL bằng cách sử dụng C++ và Prepared Statements. Bạn sẽ học cách kết nối đến MySQL, thực hiện truy vấn và chia dữ liệu thành các trang nhỏ hơn để hiển thị.
Mã C++
#include <iostream>
#include <mysql/mysql.h>
// Thông tin kết nối MySQL
#define SERVER "localhost"
#define USER "root"
#define PASSWORD "password"
#define DATABASE "test_db"
int main() {
MYSQL *conn;
MYSQL_STMT *stmt;
MYSQL_RES *result;
MYSQL_ROW row;
conn = mysql_init(NULL);
// Kết nối đến database
if (!mysql_real_connect(conn, SERVER, USER, PASSWORD, DATABASE, 0, NULL, 0)) {
std::cerr << "Kết nối thất bại: " << mysql_error(conn) << std::endl;
return 1;
}
// Câu truy vấn với LIMIT và OFFSET
int page = 1; // Trang đầu tiên
int pageSize = 5; // Số bản ghi mỗi trang
int offset = (page - 1) * pageSize;
std::string query = "SELECT id, name FROM users LIMIT ? OFFSET ?";
// Chuẩn bị truy vấn
stmt = mysql_stmt_init(conn);
if (!stmt) {
std::cerr << "Không thể khởi tạo Prepared Statement: " << mysql_error(conn) << std::endl;
return 1;
}
if (mysql_stmt_prepare(stmt, query.c_str(), query.length())) {
std::cerr << "Chuẩn bị truy vấn thất bại: " << mysql_stmt_error(stmt) << std::endl;
return 1;
}
// Thiết lập tham số
MYSQL_BIND bind[2];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = (char *)&pageSize;
bind[1].buffer_type = MYSQL_TYPE_LONG;
bind[1].buffer = (char *)&offset;
if (mysql_stmt_bind_param(stmt, bind)) {
std::cerr << "Thiết lập tham số thất bại: " << mysql_stmt_error(stmt) << std::endl;
return 1;
}
// Thực hiện truy vấn
if (mysql_stmt_execute(stmt)) {
std::cerr << "Thực hiện truy vấn thất bại: " << mysql_stmt_error(stmt) << std::endl;
return 1;
}
// Lấy kết quả
result = mysql_stmt_result_metadata(stmt);
int num_fields = mysql_num_fields(result);
// Đọc và in kết quả
MYSQL_BIND resultBind[num_fields];
memset(resultBind, 0, sizeof(resultBind));
unsigned long length[2];
char id[10];
char name[50];
bool is_null[2];
bool error[2];
resultBind[0].buffer_type = MYSQL_TYPE_STRING;
resultBind[0].buffer = id;
resultBind[0].buffer_length = sizeof(id);
resultBind[0].is_null = &is_null[0];
resultBind[0].length = &length[0];
resultBind[0].error = &error[0];
resultBind[1].buffer_type = MYSQL_TYPE_STRING;
resultBind[1].buffer = name;
resultBind[1].buffer_length = sizeof(name);
resultBind[1].is_null = &is_null[1];
resultBind[1].length = &length[1];
resultBind[1].error = &error[1];
if (mysql_stmt_bind_result(stmt, resultBind)) {
std::cerr << "Bind kết quả thất bại: " << mysql_stmt_error(stmt) << std::endl;
return 1;
}
while (!mysql_stmt_fetch(stmt)) {
std::cout << "ID: " << id << ", Name: " << name << std::endl;
}
// Dọn dẹp
mysql_free_result(result);
mysql_stmt_close(stmt);
mysql_close(conn);
return 0;
}
Giải thích chi tiết từng dòng code
mysql_real_connect
: Kết nối đến database MySQL với thông tin xác thực.mysql_stmt_prepare
: Chuẩn bị câu truy vấn với LIMIT và OFFSET cho phân trang.mysql_stmt_bind_param
: Gán tham số vào câu truy vấn (pageSize và offset).mysql_stmt_execute
: Thực hiện truy vấn với các tham số đã gán.mysql_stmt_bind_result
: Gán kết quả truy vấn vào biến để đọc và hiển thị.
Yêu cầu hệ thống:
- C++: C++11 trở lên
- MySQL Connector/C++: Phiên bản mới nhất phù hợp với hệ thống
Cách cài đặt các thư viện:
- Cài đặt MySQL Connector/C++:
- Ubuntu:
sudo apt-get install libmysqlclient-dev
- Windows: Tải và cài đặt từ trang chủ MySQL.
- Ubuntu:
Lời khuyên:
- Luôn kiểm tra kết nối và kết quả truy vấn để tránh lỗi runtime.
- Sử dụng Prepared Statements giúp tăng tính bảo mật và hiệu suất khi làm việc với MySQL.