一、连接MYSQL

在使用C语言操作MYSQL数据库之前,需要先与数据库建立连接,下面是建立连接需要用到的函数(按使用顺序),只需要将函数例程跟着过一遍,我们的C程序就成功连接到我们的数据库了。(附函数参数介绍)

连接实例

int main()
{
	MYSQL mysql;
	if(mysql_init(&mysql) == NULL)	//初始化句柄mysql
	{
		printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
		exit(1);
	}
	if (mysql_library_init(0, NULL, NULL) != 0) 	//初始化mysql数据库
	{
		fprintf(stderr, "could not initialize MySQL client library\n");
		exit(1);
	}
	if (NULL == mysql_real_connect
				(&mysql,
                "127.0.0.1",
                "root",
                "**********",
                "testdb",
                0,
                NULL,
                0)
    	)						//与mysql服务器建立连接	
	{
		printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
		exit(1);
	}
	if(mysql_set_character_set(&mysql, "utf8") != 0)	//设置中文字符集
	{
		printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
		exit(1);
	}
	printf("connect success!\n");

	//
	//中间部分为程序的主题部分
	//
	
	mysql_close(&mysql);
	mysql_library_end();
	return 0;
}

1.MYSQL *mysql_init(MYSQL *mysql)

分配或初始化一个适用于 mysql_real_connect() 的 MYSQL 对象。 如果 mysql 是 NULL 指针,则该函数分配、初始化并返回一个新对象。 否则,初始化对象并返回对象的地址。 如果 mysql_init() 分配了一个新对象,则在调用 mysql_close() 关闭连接时将其释放。

返回值:
一个初始化的 MYSQL* 处理程序。 如果没有足够的内存来分配新对象,则为 NULL。

使用实例:

MYSQL mysql;
if(mysql_init(&mysql) == NULL)
{
	printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
	exit(1);
}

2.int mysql_library_init(int argc,char **argv,char **groups)

在非多线程环境中,mysql_init() 根据需要自动调用 mysql_library_init()。 但是,mysql_library_init() 在多线程环境中不是线程安全的,因此 mysql_init() 也不是线程安全的。 在调用 mysql_init() 之前,要么在产生任何线程之前调用 mysql_library_init(),要么使用互斥锁来保护 mysql_library_init() 调用。 这应该在任何其他客户端库调用之前完成。

也就是说,这个函数在单线程的程序中不是必须的;但是在我的聊天室中用到了多线程,因此需要调用这个函数。

argc、argv 和 groups 参数未使用。 在较旧的 MySQL 版本中,它们用于链接到不再支持的嵌入式服务器的应用程序。 现在调用应该写成 mysql_library_init(0, NULL, NULL)。

返回值:
成功为零。 如果发生错误,则非零。

使用实例

if (mysql_library_init(0, NULL, NULL) != 0) 
{
	fprintf(stderr, "could not initialize MySQL client library\n");
	exit(1);
}

3. MYSQL *mysql_real_connect()

mysql_real_connect() 尝试建立与主机上运行的 MySQL 服务器的连接。 在执行任何其他需要有效 MYSQL 连接处理程序结构的 API 函数之前,客户端程序必须成功连接到服务器。

由于这个函数的参数过多,故将函数原型放在下面:

MYSQL *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 client_flag)
  1. MYSQL *mysql

    这里的mysql就是之前mysql_init()初始化的句柄

  2. const char *host

    host 的值可以是主机名或 IP 地址,一般我们连接自己主机上的数据库,就写"127.0.0.1"

  3. const char *user

    user 参数包含用户的 MySQL 登录 ID,一般都为"root"

  4. const char *passwd

    passwd 参数包含用户的密码

  5. const char *db

    db 是数据库名称

  6. unsigned int port

    该值用作 TCP/IP 连接的端口号

  7. const char *unix_socket

    我们一般用NULL

  8. unsigned long client_flag

    client_flag 的值通常为 0

关于本函数,如果想了解更多更详细的内容,可以参考MYSQL文档

使用实例:

if (NULL == mysql_real_connect
				(&mysql,
                "127.0.0.1",
                "root",
                "**********",	//这里输自己的密码
                "testdb",
                0,
                NULL,
                0)
    )
{
	printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
	exit(1);
}

4. int mysql_set_character_set(MYSQL *mysql,const char *csname)

设置默认字符集,这里我们需要设置中文字符集,不然会出现乱码

返回值:
成功为零。 如果发生错误,则非零

使用实例

if(mysql_set_character_set(&mysql, "utf8") != 0)
{
	printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
	exit(1);
}

5.void mysql_close(MYSQL *mysql)

在主线程的最后不要忘记断开与MYSQL的连接

6.mysql_library_end(void)

为避免在应用程序使用库完成后(例如,关闭与服务器的连接后)发生内存泄漏,请务必显式调用 mysql_library_end()。 这使得可以执行内存管理来清理和释放库使用的资源。

使用实例

mysql_close(&mysql);
mysql_library_end();
return 0;

二、使用MYSQL

在使用C语言操作MYSQL的时候,最重要的还是MYSQL的基本语法。因为使用C语言操作MYSQL的时候,不过是把sql的语法去掉分号后放到字符数组里,再作为参数让函数去执行。

使用实例

int ret;
char query_str[BUFSIZE];
MYSQL mysql;
MYSQL *res;
MYSQL row;

strcpy(query_str, "select * from UserData");
ret = mysql_real_query(&mysql, query_str, strlen(query_str))
if(ret != 0)
{
	printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
	exit(1);
}
res	= mysql_store_result(&mysql);
if(res == NULL)
{
	//如果mysql_error()返回NULL的话,证明没有错误发生
	if(strcmp(mysql_error(&mysql), "") != 0)
	{
		printf("%d : error : %s\n", __LINE__, mysql_error(&mysql));
		exit(1);
	}
}
//row(MYSQL_ROW)作为一个二级指针,我们在使用时要注意数组越界问题
while(row = mysql_fetch_row(res))
{
	//...
}

1.int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length)

mysql_real_query() 执行 stmt_str 指向的 SQL 语句,字符串长度字节长。 通常,字符串必须由单个 SQL 语句组成,没有终止分号或 \g。 如果启用了多语句执行,则字符串可以包含多个用分号分隔的语句。

返回值
成功为零。 如果发生错误,则非零。

2.MYSQL_RES *mysql_store_result(MYSQL *mysql)

得到MYSQL_RES这个句柄。
mysql_store_result()用来获得上一个语句产生的结果集,比所说select、show语句产生的搜索结果,但如果上一个语句没有产生结果集,那么函数返回NULL(注意这个NULL要与发生错误时返回的NULL作区分)。

返回值
指向带有结果的 MYSQL_RES 结果结构的指针。 如果语句未返回结果集或发生错误,则为 NULL。 要确定是否发生错误,请检查 mysql_error() 是否返回非空字符串、mysql_errno() 是否返回非零或 mysql_field_count() 是否返回零。

在得到MYSQL_RES *这个句柄之后,我们就可以知道有关这个数据表的所有信息。

(1).mysql_num_rows(MYSQL_RES *res)
(2).mysql_num_fields(MYSQL_RES *res)

这两个函数分别可以得到数据表中的行数和列数,比较简单,这里不细说。具体可以参考MYSQL文档

3.MYSQL_ROW mysql_fetch_row(MYSQL_RES *res)

检索结果集的下一行
如果我们想要打印出整个数据表的话,可以这样使用:

int i;
int fields;
fields = mysql_num_fields(res);		//获得数据表的列数
while(row = mysql_fetch_row(res))
{
	for(i=0; i<fields; i++)
	{
		printf("%-20s", row[i]);
	}
	printf("\n");
}

很重要的一个函数sprintf()

在C语言操作数据库时,sprintf()函数可以很方便的帮我们组装好一个语句:

sprintf(query_str, "select * from UserData \
where username = \"%s\"", username);

程序封装

在项目中,我们可能会频繁的使用MYSQL,为了提高编程效率(频繁的对没有结果集的sql语句调用mysql_store_result()并不会导致显著的性能下降),我们可以把常用的MYSQL函数封装一下:
对于有结果集的sql语句,我们可以用返回的句柄res对结果进行操作。

MYSQL_RES *my_real_query(MYSQL *mysql, MYSQL_RES *res, char *q, int line)
{
    int ret;
    char query_str[BUFSIZE];
    strcpy(query_str, q);
    ret = mysql_real_query(mysql, query_str, strlen(query_str));
    if(ret != 0)
    {
        printf("%d : error : %s\n", line, mysql_error(mysql));
        exit(1);
    }
    res = mysql_store_result(mysql);
    if(res == NULL)
    {
        if(strcmp(mysql_error(mysql), "") != 0)
        {
            printf("%d : error : %s\n", line, mysql_error(mysql));
            exit(1);
        }
    }
    return res;
}

总结

在进行聊天室项目的时候需要用到MYSQL,现在两周时间过去了,我的聊天室项目也已经基本完成了,这里想记录一下在聊天室项目中非常重要的一个工具——MYSQL。
由于我此前从未接触过MYSQL,在项目进行过程中也基本都是现学现用,关于MYSQL的使用我还只是刚入门,希望这篇博客可以给大家在初次接触MYSQL的时候提供一点引导。

本文参考:
https://dev.mysql.com/doc/

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐