使用vs2019对window11中的数据库进行连接
首先需要把mysql中的头文件和库文件放入到c++项目工程中
1.打开安装MySQL的目录,在windows系统中如果是默认路径,应该和我的是一样的:C:\Program Files\MySQL\MySQL Server 8.0
2.找到include,和lib文件,include文件是包含的头文件,lib文件是包含的库文件
3.在创建的c++工程中加入include,lib文件路径,按一下步骤
1.工程中的项目找到属性
2.到 VC++ 目录 中的包含目录和库目录分别加入include文件和lib文件的路径,
这是我的路径:include文件路径:C:\Program Files\MySQL\MySQL Server 8.0\include
lib文件路径:C:\Program Files\MySQL\MySQL Server 8.0\lib
3. 到 链接器 中的 输入 中的 附加依赖项中 加入 libmysql.lib 的依赖:
4.还需要把下图中的 libmysql.dll 的文件复制到 C:\Windows\System32 目录中
例子:
#define _CRT_SECURE_NO_WARNINGS#include#include#include#includeintmain(){
int sr;
srand((unsigned)time(NULL));
sr = rand() % 50 + 1;
//固定不变的
MYSQL mysql; //一个数据库结构体
MYSQL_RES* res; //一个结果集结构体
MYSQL_ROW row; //char** 二维数据,存放一条条记录
//初始化数据库
mysql_init(&mysql);
//设置编码方式
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
//连接数据库 //ip地址 //用户名 //密码 //数据库名
if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL)
{
printf("错误原因:%s\n", mysql_error(&mysql));
printf("连接失败\n");
exit(-1);
}
//往数据库中插入一个随机数
char* str1 = "insert into rand values(";
char sql_insert[200];
sprintf(sql_insert, "%s%d%s", str1, sr, ")");
mysql_query(&mysql, sql_insert); //sql语句提交
//查询数据
mysql_query(&mysql, "select * from rand");
//获取结果集
res = mysql_store_result(&mysql);
//给ROW赋值,判断ROW是否为空,不为空就打印数据
while (row = mysql_fetch_row(res))
{
printf("%s\n", row[0]);
}
//释放结果集
mysql_free_result(res);
//关闭数据库
mysql_close(&mysql);
//停留等待
system("pause");
return0;
}
使用c++语句对数据库进行增删改查,在使用c++中string类型时,需要把string类型转换为c中的类型,使用mysql_query函数把sql语句提交,查询成功返回0,结果会被保存到mysql对象中,查询失败会返回非0值:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
usingnamespace std;
intmain(){
MYSQL mysql;
MYSQL_RES* res;
MYSQL_ROW row;
mysql_init(&mysql);
if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL)
{
printf("错误提示:%s\n", mysql_error(&mysql));
printf("连接失败\n");
}
//设置字符集
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
string str1 = "alter table tb_77 modify sex varchar(20)";//修改表类型失败
mysql_query(&mysql, str1.c_str());
string str = "insert into tb_77 values(5,'sdmqy','h')";//增加数据成功,不可以增加汉字
mysql_query(&mysql, str.c_str());
printf("%s", str.c_str());
string str2 = "delete from tb_77 where sex = '女';";//删除数据成功
mysql_query(&mysql, str2.c_str());
string str3 = "update tb_77 set name = 'ttb' where id = 2";//更改也行
mysql_query(&mysql, str3.c_str());
mysql_close(&mysql);
return0;
}
1. mysql句柄类(是一个结构体)
1 |
MYSQL mysql; |
该类在c++中操作数据库都要使用到
结构体原型:
typedef struct MYSQL {
NET net; /* Communication parameters */
unsigned char *connector_fd; /* ConnectorFd for SSL */
char *host, *user, *passwd, *unix_socket, *server_version, *host_info;
char *info, *db;
struct CHARSET_INFO *charset;
MYSQL_FIELD *fields;
struct MEM_ROOT *field_alloc;
uint64_t affected_rows;
uint64_t insert_id; /* id if insert on table with NEXTNR */
uint64_t extra_info; /* Not used */
unsigned long thread_id; /* Id for connection in server */
unsigned long packet_length;
unsigned int port;
unsigned long client_flag, server_capabilities;
unsigned int protocol_version;
unsigned int field_count;
unsigned int server_status;
unsigned int server_language;
unsigned int warning_count;
struct st_mysql_options options;
enum mysql_status status;
enum enum_resultset_metadata resultset_metadata;
bool free_me; /* If free in mysql_close */
bool reconnect; /* set to 1 if automatic reconnect */
/* session-wide random string */
char scramble[SCRAMBLE_LENGTH + 1];
LIST *stmts; /* list of all statements */
const struct MYSQL_METHODS *methods;
void *thd;
/*
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
from mysql_stmt_close if close had to cancel result set of this object.
*/
bool *unbuffered_fetch_owner;
void *extension;
} MYSQL;
2.MYSQL_RES查询结果集(是一个结构体)
2 |
MYSQL_RES * res=nullptr; |
用来保存查询到的所有结果
结构体原型:
typedef struct MYSQL_RES {
uint64_t row_count;
MYSQL_FIELD *fields;
struct MYSQL_DATA *data;
MYSQL_ROWS *data_cursor;
unsigned long *lengths; /* column lengths of current row */
MYSQL *handle; /* for unbuffered reads */
const struct MYSQL_METHODS *methods;
MYSQL_ROW row; /* If unbuffered read */
MYSQL_ROW current_row; /* buffer to current row */
struct MEM_ROOT *field_alloc;
unsigned int field_count, current_field;
bool eof; /* Used by mysql_fetch_row */
/* mysql_stmt_close() had to cancel this result */
bool unbuffered_fetch_cancelled;
enum enum_resultset_metadata metadata;
void *extension;
} MYSQL_RES;
3.MYSQL_ROW获取结果集中的内容:本质上是一个char类型的二级指针
3. |
MYSQL_ROW row |
该变量可以获取到结果集中的数据
4.MYSQL_FIELD获取结果集中表的所有内容(是一个结构体)
结构体原型:
typedef struct MYSQL_FIELD {
char *name; /* Name of column */
char *org_name; /* Original column name, if an alias */
char *table; /* Table of column if column was a field */
char *org_table; /* Org table name, if table was an alias */
char *db; /* Database for table */
char *catalog; /* Catalog for table */
char *def; /* Default value (set by mysql_list_fields) */
unsigned long length; /* Width of column (create length) */
unsigned long max_length; /* Max width for selected set */
unsigned int name_length;
unsigned int org_name_length;
unsigned int table_length;
unsigned int org_table_length;
unsigned int db_length;
unsigned int catalog_length;
unsigned int def_length;
unsigned int flags; /* Div flags */
unsigned int decimals; /* Number of decimals in field */
unsigned int charsetnr; /* Character set */
enum enum_field_types type; /* Type of field. See mysql_com.h for types */
void *extension;
} MYSQL_FIELD;
部分API函数
函数 |
作用 |
mysql_init() |
获取或初始化MYSQL结构。 |
mysql_real_connect() |
连接到MySQL服务器。 |
mysql_query() |
执行指定为“以Null终结的字符串”的SQL查询。 |
mysql_store_result() |
检索完整的结果集至客户端。 |
mysql_use_result() |
初始化逐行的结果集检索 |
mysql_fetch_field() |
返回下一个表字段的类型。 |
mysql_fetch_fields() |
返回所有字段结构的数组。 |
mysql_fetch_lengths() |
返回当前行中所有列的长度。 |
mysql_fetch_row() |
从结果集中获取下一行 |
mysql_field_count() |
返回上次执行语句的结果列的数目。 |
mysql_free_result() |
释放结果集使用的内存。 |
mysql_close() |
关闭服务器连接。 |
mysql_autocommit() |
切换 autocommit模式,ON/OFF |
mysql_commit() |
提交事务。 |
mysql_errno() |
返回上次调用的MySQL函数的错误编号 |
mysql_options() |
为mysql_connect()设置连接选项 |
mysql_ping() |
检查与服务器的连接是否工作,如有必要重新连接。 |
在下列函数中,从连接数据库到获取数据库中的数据主要使用到1-7的函数。
函数原型:
MYSQL *mysql_init(MYSQL *mysql)
说明:
1.如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。
2.否则,将初始化对象,并返回对象的地址。
3.如果mysql_init()分配了新的对象,应当在程序中调用mysql_close() 来关闭连接,以释放对象
参数解释:
返回值:初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL。
错误,在内存不足的情况下,返回NULL
函数原型:
mysql_real_connect(
MYSQL *mysql, ///< 数据库句柄
constchar *host, ///< 主机名
constchar *user, ///< 用户名
constchar *passwd,///< 密码
constchar *db, ///< 数据库名
unsignedint port, ///< 端口号(MySQL为3306)
constchar *unix_socket,///< unix_socket–unix连接方式,为NULL时表示不使用socket或管道机制
unsignedlong clientflag ///< clientflag–Mysql运行为ODBC数据库的标记,一般取0,该参数可以设置提交的sql语句为多条语句
);
作用:连接数据库引擎,通过函数mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。
返回值:如果连接成功,返回MYSQL*连接句柄。如果连接失败,返回NULL。对于成功的连接,返回值与第1个参数的值相同。
函数原型:
int STDCALL mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
说明:执行由“Null终结的字符串”查询指向的SQL查询。
正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。
如果允许多语句执行,字符串可包含多条由分号隔开的语句。(“多查询执行的C API处理”)mysql_query()
不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之(二进制数据可能包含字符‘\0’,
mysql_query()会将该字符解释为查询字符串结束)。如果希望了解查询是否应返回结果集,
可使用mysql_field_count()进行检查。
返回值:如果查询成功,返回0。如果出现错误,返回非0值。
int mysql_query(MYSQL *mysql, const char *query)
返回值:如果查询成功,返回0。如果出现错误,返回非0值。
参数解释:
参数mysql:前面使用MYSQL结构体定义的变量;
参数query:sql语句
参数length:sql语句的长度
函数原型:
MYSQL_RES *mysql_store_result(MYSQL *mysql)
说明:
1.对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等)
,必须调用mysql_store_result()或mysql_use_result() 。
2.如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。
3.如果查询未返回结果集,mysql_store_result()将返回Null指针(例如,
如果查询是INSERT语句)。
4.如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()
是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0,
可以检查是否出现了错误。
5.如果未返回行,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。
6.一旦调用了mysql_store_result()并获得了不是Null指针的结果,可调用
mysql_num_rows()来找出结果集中的行数。
7.可以调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()和
mysql_row_tell()来获取或设置结果集中的当前行位置。
8.一旦完成了对结果集的操作,必须调用mysql_free_result()。
返回值:具有多个结果的MYSQL_RES结果集合。如果出现错误,返回NULL。
MYSQL_RES * mysql_use_result(MYSQL *mysql);
说明:调用mysql_use_result初始化检索,以便于后面一行一行的读取结果集,而它本身并没有从
服务器读取任何数据,这种方式较之第一种速度更快且所需内存更少,但它会绑定服务器,阻止其他线程
更新任何表,而且必须重复执行mysql_fetch_row读取数据,直至返回NULL,否则未读取的行会在下一
次查询时作为结果的一部分返回,故经常我们使用mysql_store_result。
函数原型:
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result)
说明:
1.在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。
2.在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,
mysql_fetch_row()返回NULL。
3.行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用
mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],
访问这些值的指针。
4.可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及
包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,
字段为NULL,否则字段为空。
参数:是函数mysql_store_result或mysql_use_result的返回值
返回值:下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。
函数原型:
void mysql_free_result(MYSQL_RES *result)
说明:释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为结果
集分配的内存。完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。
函数原型:
void mysql_close(MYSQL *mysql)
说明:关闭前面打开的连接。如果句柄是由mysql_init()或mysql_connect()自动分配的,
mysql_close()还将解除分配由mysql指向的连接句柄。
函数原型:
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
函数原型:
MYSQL_FIELD *STDCALL mysql_fetch_fields(MYSQL_RES *res);
函数原型:
unsigned long *STDCALL mysql_fetch_lengths(MYSQL_RES *result);
函数原型:
unsigned int mysql_field_count(MYSQL *mysql)
说明:此函数的正常用法是当返回 mysql_store_result() 时(因此您没有结果集) 指针)。
在这种情况下,您可以调用 mysql_field_count() 来 确定 mysql_store_result()
是否应 产生了非空的结果
在mysql中事务是默认自动提交的,如果需要提交的事务多,对我们的操作会有影响,所以需要设置事务为手动提交
mysql_autocommit(MYSQL* , mode) 设置事务是否自动提交函数
参数:mode如果为“1”,自动提交,为“0”为手动提交 返回值:提交成功返回0,否则返回非0
mysql_commit(MYSQL* mysql) 事务提交函数
返回值:成功返回0,否则返回非0
mysql_rollback(MYSQL* mysql) 事务回滚函数
返回值:成功返回0,否则返回非0
6.打印错误信息:
const char* mysql_error(MYSQL* mysql):返回错误信息的描述
const char* mysql_errno(MYSQL* mysql):返回错误的编号
#define _CRT_SECURE_NO_WARNINGS
#include
#include
usingnamespace std;
intmain(){
//创建句柄
MYSQL mysql;
//创建数据集变量
MYSQL_RES* res = nullptr;
//创建结果集变量
MYSQL_ROW row;
//创建一个结构体
MYSQL_FIELD* field;
//初始化数据库句柄
mysql_init(&mysql);
//设置字符集
//mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
mysql_set_character_set(&mysql, "gbk");
//开始连接数据库
if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0))
{
cout << "连接成功" << endl;
}
else
{
cout << "连接失败" << endl;
return0;
}
//设置事务
mysql_autocommit(&mysql, "1");
//增加数据
string str1 = "insert into tb_912 values(2, 'xiaoming', '李四');";
char ssql[1024];
//使用sprintf拼出来的语句是一个标准的c语言字符串,可以使用该函数插入变量值
sprintf(ssql, "insert into tb_912 values(%d, '%s', '%s');", 3, "daming", "17777777772");
if (mysql_query(&mysql, ssql))//该语句提交成功返回0,失败返回1
{
cout << "提交失败" << endl;
}
else
{
cout << "提交成功" << endl;
}
//提交语句
mysql_query(&mysql, str1.c_str());
//删除数据
string str3 = "delete from tb_912 where id = 2";
mysql_query(&mysql, str3.c_str());
//修改数据
string str4 = "update tb_912 set name = '张三' where id = 1";
mysql_query(&mysql, str4.c_str());
//查询数据
string str2 = "select * from tb_912";
mysql_query(&mysql, str2.c_str());
//事务提交
mysql_commit(&mysql);
//获取里面的结果集
res = mysql_store_result(&mysql);
//拿到结果集得列数,调用的是 mysql_store_result() 的返回值,
unsignedint a = mysql_num_fields(res);
cout <<"表得列数:"<< a << endl;
//使用 mysql_fetch_fields() 函数获取列的名字,返回的是一个结构体数组
field = mysql_fetch_fields(res);
for (unsigned i = 0; i < a; i++)
{
cout << "当前列的名字:" << field[i].name << endl;//取出名字
}
unsignedlong* lengths;
//从结果集中获取到数据 mysql_fetch_row() 获取结果集中的一行数据,
//成功:返回记录当前行中每个字段的值,失败:返回一个null
while (row = mysql_fetch_row(res))
{
printf("%s %s %s \n", row[0], row[1], row[2]);
//获取列中字段的长度
lengths = mysql_fetch_lengths(res);//返回的是一个数组地址
for (unsignedint i = 0; i < a; i++)
{
cout << "当前列的长度:" << lengths[i] << endl;//列数会构成一个数组
}
}
//释放结果集
mysql_free_result(res);
//关闭mysql实例
mysql_close(&mysql);
return0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include