在实际应用中,我们不可能在命令行登录进数据库进行数据的查询、插入等操作,用户一般是使用一个界面良好的应用程序软件来对数据进行管理。为了方便应用程序的开发,MySQL提供了多种编程语言(C、perl、php等)的编程接口,供开发者使用。
对于C语言来说,MySQL提供了C语言客户机库,它允许从任何C程序的内部访问MySQL数据库,客户机实现API,API定义了客户机如何建立和执行与服务器的通信。使用C语言开发MySQL项目具有更好的安全性和性能,C语言API是与MySQL一起提供的,包含在mysqlclient库文件中,用于连接和执行数据库查询。
在命令行输入以下指令进行MySQL、客户端、客户端接口库的安装。
安装mysql
sudo apt-get install mysql-server
安装mysql客户端
sudo apt install mysql-client
安装mysql客户端接口库
sudo apt-get install libmysqlclient-dev
一、MySQL为C语言操作定义的数据类型
1、MYSQL
MYSQL结构代表一个数据库连接句柄,包含有关服务器的连接状态的信息,几乎所有函数都是用到它。其定义如下:
typedef struct st_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_st *charset;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
my_ulonglong 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;
my_bool free_me; /* If free in mysql_close */
my_bool reconnect; /* set to 1 if automatic reconnect */
/* session-wide random string */
char scramble[SCRAMBLE_LENGTH+1];
/* Set if this is the original connection, not a master or a slave we have added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() */
my_bool rpl_pivot;
/* Pointers to the master, and the next slave connections, points to itself if lone connection. */
struct st_mysql* master, *next_slave;
struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
/* needed for send/read/store/use result to work correctly with replication */
struct st_mysql* last_used_con;
LIST *stmts; /* list of all statements */
const struct st_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. */
my_bool *unbuffered_fetch_owner;
/* needed for embedded server - no net buffer to store the 'info' */
char *info_buffer;
void *extension;
} MYSQL;
2、MYSQL_RES
MYSQL_RES结构代表返回行的查询结果(SELECT、SHOW、DESCRIBE等),从数据库读取数据,最后就是从MYSQL_RES中读取数据。其定义如下:
typedef struct st_mysql_res
{
my_ulonglong row_count;
MYSQL_FIELD *fields;
MYSQL_DATA *data;
MYSQL_ROWS *data_cursor;
unsigned long *lengths; /* column lengths of current row */
MYSQL *handle; /* for unbuffered reads */
const struct st_mysql_methods *methods;
MYSQL_ROW row; /* If unbuffered read */
MYSQL_ROW current_row; /* buffer to current row */
MEM_ROOT field_alloc;
unsigned int field_count, current_field;
my_bool eof; /* Used by mysql_fetch_row */
/* mysql_stmt_close() had to cancel this result */
my_bool unbuffered_fetch_cancelled;
void *extension;
} MYSQL_RES;
二、基础函数
1、分配或初始化与mysql_real_connect()相适应的MYSQL对象
MYSQL* mysql_init(MYSQL* mysql)
如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果mysql_init()分配了新的对象,应当在程序中调用mysql_close() 来关闭连接,以释放对象。
2、连接到MySQL server
MYSQL* mysql_real_connect(MYSQL* mysql,const char* host,const charuser,
const char passwd,const char* db,unsigned int port,
const char* unix_socket,unsigned long client_flag)
在能够执行需要有效MySQL连接句柄结构的任何其它API函数之前,mysql_real_connect() 必须成功完成。
参数:
“mysql”——已有MYSQL结构的地址。
“host”——必须是主机名或IP地址。如果host是NULL或字符串“localhost”,连接将被视为与本地主机连接
“user”——用户名
“passwd”——用户的密码
“db”——数据库名称
“port”——如果“port”不是0,其值将用作TCP/IP连接的端口号
“unix_socket”——通常指定为NULL
“client_flag”——通常为0,但是,也能将其设置为具有特定功能的标志组合。
3、执行字符串指定的sql查询语句
int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)
执行由指针query指向的字符串进行SQL查询,字符串长度应为length。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含由分号隔开的多条语句。
如果查询成功,函数返回0。如果出现错误,函数返回非0值。
4、向客户端检索完整的结果集
MYSQL_RES* mysql_store_result(MYSQL* mysql)
对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()。
mysql_store_result()将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中。如果查询未返回结果集,mysql_store_result()将返回Null指针。
5、获取结果集中的行数
my_ulonglong mysql_num_rows(MYSQL_RES *result)
6、获取结果集中的列数
unsigned int mysql_num_fields(MYSQL_RES *result)
7、从结果集中获取下一行
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
返回值:下一行的MYSQL_ROW结构,如果没有更多的行可检索或者发生错误时,则返回NULL。
8、获取最近查询的列数
unsigned int mysql_field_count(MYSQL* mysql)
返回:最近查询的列数
该函数的正常使用是在 mysql_store_result() 返回 NULL(因而没有结果集指针)时。在这种情况下,可调用 mysql_field_count() 来判定 mysql_store_result() 是否应生成非空结果。这样客户端就能采取恰当的动作,而无需知道查询是否是 SELECT (或类似的SELECT的)语句。
9、返回最近调用MySQL函数发生的错误信息
const char* mysql_error(MYSQL* mysql)
返回值:描述错误信息的以null结尾的字符串,如果未发生错误,则返回空字符串。
10、关闭一个server连接
void mysql_close(MYSQL* mysql)
关闭前面已经打开的连接。如果句柄是由mysql_init() 或mysql_connect() 自定分配的,mysql_close() 还将解除分配由mysql指向的连接句柄。
三、与MySQL交互时,应用程序应使用该一般性原则:
1、 通过调用mysql_init()初始化连接处理程序,并通过调用mysql_real_connect()连接到服务器。
2、 发出SQL语句并处理其结果。
3、 通过调用mysql_close(),关闭与MySQL服务器的连接。
四、实现代码
1、查询数据
#include <stdio.h>
#include <mysql/mysql.h>
#include <string.h>
int main(int argc, const char *argv[])
{
MYSQL mysql;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
char *query_str = NULL;
int rc, i, fields;
int rows;
if (NULL == mysql_init(&mysql))
{
printf("mysql_init(): %s\n", mysql_error(&mysql));
return -1;
}
if (NULL == mysql_real_connect(&mysql,
"localhost",
"root",
"123456",
"usrinfo",
0,
NULL,
0)){
printf("mysql_real_connect(): %s\n", mysql_error(&mysql));
return -1;
}
printf("Connected MySQL successful! \n");
//然后查询插入删除之后的数据
query_str = "select * from usr_info";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
res = mysql_store_result(&mysql);
if (NULL == res) {
printf("mysql_restore_result(): %s\n", mysql_error(&mysql));
return -1;
}
rows = mysql_num_rows(res);
printf("The total rows is: %d\n", rows);
fields = mysql_num_fields(res);
printf("The total fields is: %d\n", fields);
while ((row = mysql_fetch_row(res))) {
for (i = 0; i < fields; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}
mysql_free_result(res);
mysql_close(&mysql);
return 0;
}
运行
root@instance-3xw0fccv:~/mysqltest# gcc -o Mainpro select.c -L /usr/bin/mysql -lmysqlclient
root@instance-3xw0fccv:~/mysqltest# ./Mainpro
Connected MySQL successful!
The total rows is: 3
The total fields is: 3
XiaoMing 22 1999-05-06
XiaoLi 23 1998-11-18
XiaoHong 20 2001-06-24
2、插入数据
#include <stdio.h>
#include <mysql/mysql.h>
#include <string.h>
int main(int argc, const char *argv[])
{
MYSQL mysql;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
char *query_str = NULL;
int rc, i, fields;
int rows;
if (NULL == mysql_init(&mysql))
{
printf("mysql_init(): %s\n", mysql_error(&mysql));
return -1;
}
if (NULL == mysql_real_connect(&mysql,
"localhost",
"root",
"123456",
"usrinfo",
0,
NULL,
0)){
printf("mysql_real_connect(): %s\n", mysql_error(&mysql));
return -1;
}
printf("Connected MySQL successful! \n");
//执行插入请求
query_str = "insert into usr_info values ('XiaoZhang', '24','1997-02-03')";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
//然后查询插入删除之后的数据
query_str = "select * from usr_info";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
res = mysql_store_result(&mysql);
if (NULL == res) {
printf("mysql_restore_result(): %s\n", mysql_error(&mysql));
return -1;
}
rows = mysql_num_rows(res);
printf("The total rows is: %d\n", rows);
fields = mysql_num_fields(res);
printf("The total fields is: %d\n", fields);
while ((row = mysql_fetch_row(res))) {
for (i = 0; i < fields; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}
mysql_free_result(res);
mysql_close(&mysql);
return 0;
}
运行
root@instance-3xw0fccv:~/mysqltest# gcc -o Mainpro insert.c -L /usr/bin/mysql -lmysqlclient
root@instance-3xw0fccv:~/mysqltest# ./Mainpro
Connected MySQL successful!
The total rows is: 4
The total fields is: 3
XiaoMing 22 1999-05-06
XiaoLi 23 1998-11-18
XiaoHong 20 2001-06-24
XiaoZhang 24 1997-02-03
3、删除数据
#include <stdio.h>
#include <mysql/mysql.h>
#include <string.h>
int main(int argc, const char *argv[])
{
MYSQL mysql;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
char *query_str = NULL;
int rc, i, fields;
int rows;
if (NULL == mysql_init(&mysql))
{
printf("mysql_init(): %s\n", mysql_error(&mysql));
return -1;
}
if (NULL == mysql_real_connect(&mysql,
"localhost",
"root",
"123456",
"usrinfo",
0,
NULL,
0)){
printf("mysql_real_connect(): %s\n", mysql_error(&mysql));
return -1;
}
printf("Connected MySQL successful! \n");
//执行删除请求
query_str = "delete from usr_info where name='XiaoLi'";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
//然后查询插入删除之后的数据
query_str = "select * from usr_info";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
res = mysql_store_result(&mysql);
if (NULL == res) {
printf("mysql_restore_result(): %s\n", mysql_error(&mysql));
return -1;
}
rows = mysql_num_rows(res);
printf("The total rows is: %d\n", rows);
fields = mysql_num_fields(res);
printf("The total fields is: %d\n", fields);
while ((row = mysql_fetch_row(res))) {
for (i = 0; i < fields; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}
mysql_free_result(res);
mysql_close(&mysql);
return 0;
}
运行
root@instance-3xw0fccv:~/mysqltest# gcc -o Mainpro delete.c -L /usr/bin/mysql -lmysqlclient
root@instance-3xw0fccv:~/mysqltest# ./Mainpro
Connected MySQL successful!
The total rows is: 3
The total fields is: 3
XiaoMing 22 1999-05-06
XiaoHong 20 2001-06-24
XiaoZhang 24 1997-02-03
4、修改数据
#include <stdio.h>
#include <mysql/mysql.h>
#include <string.h>
int main(int argc, const char *argv[])
{
MYSQL mysql;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
char *query_str = NULL;
int rc, i, fields;
int rows;
if (NULL == mysql_init(&mysql))
{
printf("mysql_init(): %s\n", mysql_error(&mysql));
return -1;
}
if (NULL == mysql_real_connect(&mysql,
"localhost",
"root",
"123456",
"usrinfo",
0,
NULL,
0)){
printf("mysql_real_connect(): %s\n", mysql_error(&mysql));
return -1;
}
printf("Connected MySQL successful! \n");
//执行修改请求
query_str = "UPDATE usr_info SET birthday='1999-07-03',age='22' WHERE name ='XiaoHong'";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
//然后查询插入删除之后的数据
query_str = "select * from usr_info";
rc = mysql_real_query(&mysql, query_str, strlen(query_str));
if (0 != rc) {
printf("mysql_real_query(): %s\n", mysql_error(&mysql));
return -1;
}
res = mysql_store_result(&mysql);
if (NULL == res) {
printf("mysql_restore_result(): %s\n", mysql_error(&mysql));
return -1;
}
rows = mysql_num_rows(res);
printf("The total rows is: %d\n", rows);
fields = mysql_num_fields(res);
printf("The total fields is: %d\n", fields);
while ((row = mysql_fetch_row(res))) {
for (i = 0; i < fields; i++) {
printf("%s\t", row[i]);
}
printf("\n");
}
mysql_free_result(res);
mysql_close(&mysql);
return 0;
}
运行
root@instance-3xw0fccv:~/mysqltest# gcc -o Mainpro update.c -L /usr/bin/mysql -lmysqlclient
root@instance-3xw0fccv:~/mysqltest# ./Mainpro
Connected MySQL successful!
The total rows is: 3
The total fields is: 3
XiaoMing 22 1999-05-06
XiaoHong 22 1999-07-03
XiaoZhang 24 1997-02-03
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38530.html