C++连接MySQL数据库

C++连接MySQL数据库


官方API接口说明

1. MySQL常用API函数

函数签名解释
mysql_affected_rows()返回被最新的UPDATE, DELETE或INSERT查询影响的行数
void mysql_close(MYSQL *sock)关闭一个服务器连接
mysql_connect()连接一个MySQL服务器。该函数不推荐;使用mysql_real_connect()代替
mysql_change_user()改变在一个打开的连接上的用户和数据库
mysql_create_db()创建一个数据库。该函数不推荐;而使用SQL命令CREATE DATABASE
mysql_data_seek()在一个查询结果集合中搜寻一任意行
mysql_debug()用给定字符串做一个DBUG_PUSH
mysql_drop_db()销毁一个数据库。该函数不推荐;而使用SQL命令DROP DATABASE
mysql_dump_debug_info()让服务器将调试信息写入日志文件
mysql_eof()确定是否已经读到一个结果集合的最后一行。这功能被反对; mysql_errno()或mysql_error()可以相反被使用。
mysql_errno()返回最近被调用的MySQL函数的出错编号
mysql_error()返回最近被调用的MySQL函数的出错消息
mysql_escape_string()用在SQL语句中的字符串的转义特殊字符
mysql_fetch_field()返回下一个表字段的类型
mysql_fetch_field_direct ()返回一个表字段的类型,给出一个字段编号
mysql_fetch_fields()返回一个所有字段结构的数组
mysql_fetch_lengths()返回当前行中所有列的长度
mysql_fetch_row()从结果集合中取得下一行
mysql_field_seek()把列光标放在一个指定的列上
mysql_field_count()返回最近查询的结果列的数量
mysql_field_tell()返回用于最后一个mysql_fetch_field()的字段光标的位置
mysql_free_result()释放一个结果集合使用的内存
mysql_get_client_info()返回客户版本信息
mysql_get_host_info()返回一个描述连接的字符串
mysql_get_proto_info()返回连接使用的协议版本
mysql_get_server_info()返回服务器版本号
mysql_info()返回关于最近执行得查询的信息
MYSQL * mysql_init(MYSQL *mysql);获得或初始化一个MYSQL结构
mysql_insert_id()返回有前一个查询为一个AUTO_INCREMENT列生成的ID
mysql_kill()杀死一个给定的线程
mysql_list_dbs()返回匹配一个简单的正则表达式的数据库名
mysql_list_fields()返回匹配一个简单的正则表达式的列名
mysql_list_processes()返回当前服务器线程的一张表
mysql_list_tables()返回匹配一个简单的正则表达式的表名
mysql_num_fields()返回一个结果集合中的列的数量
mysql_num_rows()返回一个结果集合中的行的数量
mysql_options()设置对mysql_connect()的连接选项
mysql_ping()检查对服务器的连接是否正在工作,必要时重新连接
mysql_query()执行指定为一个空结尾的字符串的SQL查询
mysql_real_connect()连接一个MySQL服务器
mysql_real_query()执行指定为带计数的字符串的SQL查询
mysql_reload()告诉服务器重装授权表
mysql_row_seek()搜索在结果集合中的行,使用从mysql_row_tell()返回的值
mysql_row_tell()返回行光标位置
mysql_select_db()连接一个数据库
mysql_shutdown()关掉数据库服务器
mysql_stat()返回作为字符串的服务器状态
mysql_store_result()检索一个完整的结果集合给客户
mysql_thread_id()返回当前线程的ID
mysql_use_result()初始化一个一行一行地结果集合的检索

mysql_init和mysql_close

MYSQL *mysql_init(MYSQL *mysql);    // 初始化一个MYSQL 连接的实例对象
void mysql_close(MYSQL *sock);    // 释放一个MYSQL 连接实例

这个函数有两种用法:
1. 参数传NULL 值。
    // 这种情况很显然,是mysql_init() 函数内部申请了一片内存,然后返回了首地址。
    MYSQL *ms_conn = mysql_init(NULL);
    // 用完记得要释放
    mysql_close(ms_conn), ms_conn = NULL;

2. 参数传对象地址。
    // 这种情况就是使用栈内存,mysql_init() 函数显然不应该给分配堆内存。
    MYSQL ms_eg; 
    MYSQL *ms_conn = mysql_init(&ms_eg);
    // 用完记得要释放
    mysql_close(ms_conn), ms_conn = NULL;

这个函数用来分配或者初始化一个MYSQL对象,用于连接mysql服务端。如果你传入的参数是NULL指针,它将自动为你分配一个MYSQL对象,如果这个MYSQL对象是它自动分配的,那么在调用mysql_close的时候,会释放这个对象。那么,这就有可能出现一个问题,就是,当你主动调用mysql_close之后,可能因为某些原因,又调用一次mysql_close,第二次调用,有可能因为mysql已经是野指针导致程序崩溃。另外,在我的实际运用过程中,有出现一些api调用过程中出错时,自动调用了mysql_close的情况。由于这种自动调用不会被程序感知,因此程序主动close的时候会导致崩溃。为了安全起见,建议不要让mysql_init api自动创建MYSQL对象,而由自己管理这个对象,并且传入地址让它完成初始化,这样,即使你多次调用close函数,也不会出现程序崩溃的现象。

mysql_real_connect

MYSQL *STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
					   const char *user,
					   const char *passwd,
					   const char *db,
					   unsigned int port,
					   const char *unix_socket,
					   unsigned long clientflag);
连接一个MySQL服务器

mysql_query

int	STDCALL mysql_query(MYSQL *mysql, const char *q);
执行指定为一个空结尾的字符串的SQL查询

mysql_real_query/mysql_store_result/mysql_fetch_row

int    mysql_real_query(MYSQL *mysql, const char *q, unsigned long length);
说明:执行SQL
    参数1:已初始化的MYSQL 实例;
    参数2:SQL 语句;
    参数3:SQL 语句字符数。
    Zero for success. Nonzero if an error occurred.
Error:
CR_COMMANDS_OUT_OF_SYNC
    Commands were executed in an improper order.
CR_SERVER_GONE_ERROR
    The MySQL server has gone away.
CR_SERVER_LOST
    The connection to the server was lost during the query.
CR_UNKNOWN_ERROR
    An unknown error occurred.

MYSQL_RES *mysql_store_result(MYSQL *mysql);
说明:对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()mysql_use_result()获得查询结果
参数:已初始化的MYSQL 实例。

// typedef char **MYSQL_ROW; 
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
说明:检索一个结果集合的下一行。当在mysql_store_result()之后使用时,如果没有更多的行可检索时,mysql_fetch_row()返回NULL。当在mysql_use_result()之后使用时,当没有更多的行可检索时或如果出现一个错误,mysql_fetch_row()返回NULL

mysql_affected_rows

my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
mysql_affected_rows() 取得前一次 MySQL 操作所影响的记录行数。mysql_num_rows()仅对 SELECT 语句有效,要取得被 INSERT,UPDATE 或者 DE
mysql_affected_rows返回被最新的UPDATE, DELETE或INSERT查询影响的行数

mysql_field_count

unsigned int STDCALL mysql_field_count(MYSQL *mysql);
返回最近查询的结果列的数量

mysql_fetch_fields

MYSQL_FIELD *	STDCALL mysql_fetch_field(MYSQL_RES *result);
返回一个所有字段结构的数组
  
enum enum_field_types { 
    MYSQL_TYPE_DECIMAL, 
    MYSQL_TYPE_TINY,
    MYSQL_TYPE_SHORT,  
    MYSQL_TYPE_LONG,
    MYSQL_TYPE_FLOAT,  
    MYSQL_TYPE_DOUBLE,
    MYSQL_TYPE_NULL,   
    MYSQL_TYPE_TIMESTAMP,
    MYSQL_TYPE_LONGLONG,
    MYSQL_TYPE_INT24,
    MYSQL_TYPE_DATE,   
    MYSQL_TYPE_TIME,
    MYSQL_TYPE_DATETIME, 
    MYSQL_TYPE_YEAR,
    MYSQL_TYPE_NEWDATE, 
    MYSQL_TYPE_VARCHAR,
    MYSQL_TYPE_BIT,
    MYSQL_TYPE_TIMESTAMP2,
    MYSQL_TYPE_DATETIME2,
    MYSQL_TYPE_TIME2,
    MYSQL_TYPE_NEWDECIMAL=246,
    MYSQL_TYPE_ENUM=247,
    MYSQL_TYPE_SET=248,
    MYSQL_TYPE_TINY_BLOB=249,
    MYSQL_TYPE_MEDIUM_BLOB=250,
    MYSQL_TYPE_LONG_BLOB=251,
    MYSQL_TYPE_BLOB=252,
    MYSQL_TYPE_VAR_STRING=253,
    MYSQL_TYPE_STRING=254,
    MYSQL_TYPE_GEOMETRY=255
};

typedef struct st_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 */   // 字段的mysql 数据类型
  void *extension;
} MYSQL_FIELD;

mysql_fetch_lengths

unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
返回当前行中所有列的长度

mysql_free_result

void		STDCALL mysql_free_result(MYSQL_RES *result);
释放一个结果集合使用的内存

mysql_next_result

int STDCALL mysql_next_result(MYSQL *mysql);
mysql_next_result 在存储过程中,有可能返回多个结果集,mysql_store_result用来处理当前,mysql_next_result用来处理下一个.  
    Return Value	Description
0	Successful and there are more results
-1	Successful and there are no more results
>0	An error occurred

mysql_insert_id

my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
返回有前一个查询为一个AUTO_INCREMENT列生成的ID

mysql_real_escape_string

unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
					       char *to,const char *from,
					       unsigned long length);
该函数用于创建可在SQL语句中使用的合法SQL字符串
按照连接的当前字符集,将“from”中的字符串编码为转义SQL字符串。将结果置于“to”中,并添加1个终结用NULL字节。编码的字符为NUL (ASCII 0)、‘\\n’、‘\\r’、‘\\’、‘'’、‘"’、以及Control-Z(请参见9.1节,“文字值”)。(严格地讲,MySQL仅需要反斜杠和引号字符,用于引用转义查询中的字符串。该函数能引用其他字符,从而使得它们在日志文件中具有更好的可读性)。

“from”指向的字符串必须是长度字节“long”。必须为“to”缓冲区分配至少length*2+1字节。在最坏的情况下,每个字符或许需要使用2个字节进行编码,而且还需要终结Null字节。当mysql_real_escape_string()返回时,“to”的内容是由Null终结的字符串。返回值是编码字符串的长度,不包括终结用Null字符。

如果需要更改连接的字符集,应使用mysql_set_character_set()函数,而不是执行SET NAMES (或SET CHARACTER SET)语句。mysql_set_character_set()的工作方式类似于SET NAMES,但它还能影响mysql_real_escape_string()所使用的字符集,而SET NAMES则不能

2. 实例

#include<iostream>
#include<Windows.h>
#include<WinSock.h>
#include<mysql.h>

using namespace std;
#pragma comment(lib,"libmysql.lib")
#pragma comment(lib,"wsock32.lib")
MYSQL *mysql = new MYSQL;	//mysql连接  
MYSQL_FIELD *fd;			//字段列数组  
char field[32][32];			//存字段名二维数组  
MYSQL_RES *res;				//这个结构代表返回行的一个查询结果集  
MYSQL_ROW column;			//一个行数据的类型安全(type-safe)的表示,表示数据行的列, typedef char **MYSQL_ROW;	
char query[256];			//查询语句  

bool ConnectDatabase()
{
	//初始化mysql  
	mysql_init(mysql);
	//返回false则连接失败,返回true则连接成功  
	if (!(mysql_real_connect(mysql, "localhost", "root", "199618", "chatinfo", 0, NULL, 0))) //中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去  
	{
		printf("Error connecting to database:%s\n", mysql_error(mysql));
		return false;
	}
	else
	{
		printf("Connected...\n");
		return true;
	}
	return true;
}

bool QueryDatabase(std::string sql)
{
	sprintf_s(query, sql.c_str()); //执行查询语句,这里是查询所有,user是表名,不用加引号,用strcpy也可以  
	mysql_query(mysql, "set names utf8"); //设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码  
										  //返回0 查询成功,返回1查询失败  
	if (mysql_query(mysql, query))    //执行SQL语句
	{
		printf("Query failed (%s)\n", mysql_error(mysql));
		return false;
	}
	else
	{
		printf("query success\n");
	}
	//获取结果集  
	if (!(res = mysql_store_result(mysql)))   //获得sql语句结束后返回的结果集  
	{
		printf("Couldn't get result from %s\n", mysql_error(mysql));
		return false;
	}

	//打印数据行列数  
	int s32_Column = mysql_num_fields(res);
	int s32_Rows = mysql_affected_rows(mysql);

	//获取字段的信息  
	char *str_field[32];  //定义一个字符串数组存储字段信息  
	for (int i = 0; i < s32_Column; i++)  //在已知字段数量的情况下获取字段名  
	{
		str_field[i] = mysql_fetch_field(res)->name;
		printf("%10s\t", str_field[i]);
	}
	printf("\n");
	//打印获取的数据  
	while (column = mysql_fetch_row(res))   //在已知字段数量情况下,获取并打印下一行  
	{
		for (int i = 0; i < s32_Column; i++)
		{
			printf("%10s\t", column[i]);
		}
		printf("\n"); 
	}
	return true;
}

int main()
{
	if (ConnectDatabase())
	{
		std::string  sql = "select * from user";
		QueryDatabase(sql);

		sql = "delete from user where char_id = 2";
		QueryDatabase(sql);

		sql = "INSERT INTO  User\
			(nickname, birthday, address, gender)\
			VALUES\
			('CXX', '1998', 'shanghai', 0); ";
		QueryDatabase(sql);

		sql = "Update user set nickname = 'Java' where birthday = 1998";
		QueryDatabase(sql);
	}
	
	system("pause");
	return 0;
}

运行结果:

Connected...
query success
   char_id        nickname        birthday         address          gender
         1          Python        19970118        shenzhen               1
         3            Rust        19890118        shanghai               0
         4            Java            1998        shanghai               0
Query failed (Unknown column 'Lua' in 'where clause')
query success
Couldn't get result from
query success
Couldn't get result from
请按任意键继续. . .

对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()或mysql_use_result()获得查询结果.在DELETE FROM、 UPDATE和INSERT INTO中调用mysql_store_result返回NULL;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Erice_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值