MFC+MySQL应用操作
- [1. MySQL C API 相关接口](#1. MySQL C API 相关接口)
-
- [1.1 基本数据结构](#1.1 基本数据结构)
- [1.2 常用函数](#1.2 常用函数)
- [2. 连接数据库](#2. 连接数据库)
- [3. 读取数据库行数据](#3. 读取数据库行数据)
1. MySQL C API 相关接口
1.1 基本数据结构
- MYSQL是一个重要的数据结构,它代表了与MySQL服务器的连接。当你使用MySQL的C API来与MySQL服务器进行交互时,你需要首先创建一个MYSQL对象,并使用它来建立、管理和终止与MySQL服务器的连接。
MYSQL结构体包含了许多字段,这些字段用于保存连接信息、配置参数以及其他与连接相关的状态。然而,在实际编程中,你通常不需要直接访问或修改MYSQL结构体的内部字段,而是使用提供的函数来设置连接参数、建立连接、执行查询等。 - MYSQL_RES 是 MySQL C API 中定义的一个结构体,用于表示从 MySQL 服务器检索到的结果集。
- MYSQL_ROW是一个用于表示结果集中一行的数据类型。当你在MySQL数据库中执行一个SELECT查询并获取结果集后,你可以遍历这个结果集,每次迭代处理一行数据。每一行数据都被表示为一个MYSQL_ROW类型的变量,它实际上是一个指向字符串数组的指针,其中每个字符串都是该行中某一列的值。
- MYSQL_FIELD是一个结构体,用于描述结果集中的列(或称为字段)的元数据。当你执行一个查询并获取结果集时,你可以使用MYSQL_FIELD结构体来获取关于结果集中每一列的信息,如列名、数据类型、最大长度等。MYSQL_FIELD结构体通常与mysql_fetch_field()或mysql_fetch_fields()函数一起使用。这些函数允许你遍历结果集中的列,并获取每个列的MYSQL_FIELD结构体。
MYSQL结构体的应用
- 初始化:使用mysql_init()函数来初始化一个MYSQL对象。这通常是在创建新连接之前的第一步。
cpp
MYSQL *mysql = mysql_init(NULL);
if (mysql == NULL) {
// 错误处理
}
- 设置连接参数
使用mysql_real_connect()函数来设置连接参数并尝试建立连接。这个函数需要一个MYSQL对象作为参数,并接受其他参数来指定主机名、用户名、密码等。
cpp
if (!mysql_real_connect(mysql, "host", "user", "password", "database", 0, NULL, 0)) {
// 错误处理
}
- 执行查询
使用mysql_query()函数来执行SQL查询或命令。这个函数同样需要一个MYSQL对象作为参数。
cpp
if (mysql_query(mysql, "SELECT * FROM table")) {
// 错误处理
}
- 获取结果集
如果查询返回了结果集(例如SELECT查询),你可以使用mysql_store_result()或mysql_use_result()函数来获取结果集,并使用MYSQL_RES和MYSQL_ROW等结构来遍历和处理结果。 - 关闭连接
使用mysql_close()函数来关闭与MySQL服务器的连接。在调用这个函数之后,你应该避免再次使用该MYSQL对象。
cpp
mysql_close(mysql);
1.2 常用函数
MySQL C API 提供了一组函数,用于与 MySQL 数据库进行交互。以下是一些常用的基本函数接口:
初始化与连接
- mysql_init()
初始化一个 MYSQL 结构体实例。 - mysql_real_connect()
连接到 MySQL 服务器。
查询
- mysql_query() (过时的,一般用下面的函数)
发送一个 SQL 查询或命令到 MySQL 服务器。 - int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
参数说明:
mysql:一个指向 MYSQL 结构的指针,该结构包含了与 MySQL 服务器的连接信息。
query:一个指向 SQL 查询字符串的指针。
length:查询字符串的长度。如果查询字符串是以 null 结尾的,你也可以使用 strlen(query) 来获取长度,但是 mysql_real_query 允许你传递二进制数据或包含 null 字符的字符串,此时你需要明确指定 length。
函数返回值:
如果成功,mysql_real_query 返回 0。
如果失败,返回非零值。你可以使用 mysql_error(mysql) 函数来获取具体的错误信息。 - mysql_store_result()
对于 SELECT 语句,获取完整的结果集到一个 MYSQL_RES 结构中。 - mysql_use_result()
对于 SELECT 语句,获取一个指向结果集的指针,结果集将在你获取行时从服务器中检索。 - mysql_fetch_row()
从结果集中获取一行数据。 - mysql_num_rows()
获取结果集中的行数(对于使用 mysql_store_result() 的结果集)。 - mysql_num_fields()
获取结果集中的列数。 - mysql_fetch_field()
获取结果集中当前行的字段信息。 - mysql_fetch_field_direct()
根据列索引获取字段信息。
错误处理
- mysql_error()
返回最近一次调用 API 函数的错误描述。 - mysql_errno()
返回最近一次调用 API 函数的错误号。
结果集处理
- mysql_data_seek()
将结果集的行指针移动到指定的偏移量。 - mysql_free_result()
释放一个 MYSQL_RES 结构体及其关联的内存。
字段处理
- mysql_field_count()
返回最近查询的列数(对于非 SELECT 语句,返回受影响的行数)。 - mysql_field_seek()
将字段指针设置到结果集中的给定字段偏移量。
字符集处理
- mysql_set_character_set()
设置连接的默认字符集。
断开连接
- mysql_close()
关闭一个 MySQL 连接。
非阻塞连接
- mysql_options()
设置连接选项,例如使用非阻塞套接字。
其他
- mysql_get_host_info()
返回描述当前连接的字符串。 - mysql_get_proto_info()
返回当前使用的协议版本。 - mysql_get_server_info()
返回 MySQL 服务器的版本字符串。
线程安全
MySQL C API 是线程安全的,但每个线程都应该有自己的 MYSQL 结构体实例。不应在多个线程之间共享 MYSQL 结构体实例。
cpp
#include <mysql/mysql.h>
int main() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = mysql_init(NULL);
if (!mysql_real_connect(conn, "host", "user", "password", "database", 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
if (mysql_query(conn, "SELECT * FROM table")) {
fprintf(stderr, "%s\n", mysql_error(conn));
exit(1);
}
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res)) != NULL) {
// 处理行数据...
}
mysql_free_result(res);
mysql_close(conn);
return 0;
}
2. 连接数据库
将数据库操作的成员数据和成员函数全部放在一个类中封装。
cpp
bool SQLInterface::Connect_MySQL()
{
mysql_init(&mysqlCon);
//mysqlCon 数据库结构 localhost 主机名 root 用户名 "" 密码为空 mytest 数据库 3306 端口
if (!mysql_real_connect(&mysqlCon, "localhost", "root", "123456", "stuinfo", 3306, NULL, 0))
{
AfxMessageBox(_T("访问数据库失败!"));
return false;
}
else
{
AfxMessageBox(_T("成功连接数据库!"));
// 设置字符集, 使程序支持中文。
mysql_query(&mysqlCon, "SET NAMES 'GB2312'");//解决从数据库中读取数据后汉字乱码显示的问题
}
return true;
}
3. 读取数据库行数据
cpp
vector<RowInfo> SQLInterface::Get_All_Info()
{
vector<RowInfo> Info;
//C语言组合字符串
snprintf(sql, SQL_MAX, "SELECT * FROM students_scores");
//查询数据
int ret = mysql_real_query(&mysqlCon, sql, (unsigned long)strlen(sql));
//判断查询结果
if (ret)
{
AfxMessageBox(_T("查询失败!"));
return Info;
}
else
{
res = mysql_store_result(&mysqlCon); //获取结果集
while (row = mysql_fetch_row(res))
{
RowInfo stuInfo = RowInfo(atoi(row[0]), row[1], row[2],atoi(row[3]),atof(row[4]), atof(row[5]), atof(row[6]));
Info.push_back(stuInfo);
}
}
return Info;
}
- vector Info;中RowInfo结构体用于放置每行的信息