一般使用MySQL很少用命令行,一般都是通过程序内部使用,MySQL也为不同的语言定制了不同的头文件和库函数,可以在自己的程序中通过包含头文件和编译时候链接库函数来使用MySQL。
现在一般安装MySQL的时候就会自动给你安装库函数和头文件。
可以自行通过以下命令查看。
查看库函数 ls /usr/lib64/mysql
查看头文件 ls /usr/include/mysql
如果没有的话,可以通过以下命令来安装。
安装开发库 yum install -y mysql-community-devel
然后使用mysql的话,就通过包含头文件以及链接库函数来使用。
包含头文件 #include<mysql.h> / #include<mysql/mysql.h>
包含的头文件都是 mysql.h ,但是左边这种方式由于没有指定目录,因此在编译的时候需要添加指定路径
编译链接
没指定路径:g++ -o test test.cc -I/include/mysql -L/lib64/mysql -lmysqlclient
指定路径: g++ -o test test.cc -L/lib64/mysql -lmysqlclient
-I : 这里的 I 是 i 的大写,表明指定头文件的目录
-L : 表明库文件的路径
-l : 这里的 l 是 L 的小写,表明链接的库文件
如果指定了头文件的路径,编译的时候就只需要链接库了。
MySQL接口介绍
mysql_init()
想要使用一个数据库,必须先初始化。
通过该函数可以创建一个MYSQL句柄,用来后续操作,传递的值可以为空。
mysql_real_connect()
该函数是通过 init 函数创建的句柄,来和特定的数据库进行连接。
失败返回NULL,成功则返回传入的句柄。
需要指定host,用户,密码,数据库,端口号,最后两个参数可以采用默认,直接填 nullptr 和 0 即可。
mysql_query()
该函数可以用以下达对应的命令,如 select,insert 之类的语句。
返回值为0表示成功,否则表示失败。
下面做一个实验,来一一试试上面的函数和语句。
#include<iostream>
#include<mysql/mysql.h>
#include<string>
using namespace std;
const string host = "localhost";
const string user = "lbx";
const string password = "124533lbxLBX..";
const string db = "rootDB";
const unsigned int port = 3306;
int main()
{
MYSQL * my;
my = mysql_init(nullptr);
if(my != NULL) cout<<"mysql init successed"<<endl;
else cout<<"muysql init failed!"<<endl;
if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0))
cout<<"mysql connect successed !"<<endl;
else cout<<"mysql connect failed !"<<endl;
// string sql = "insert into test (name,age) values ('tom',12)";
// string sqp = "delete from test where id = 2";
// string sql = "update test set name='jack' where id=1";
string sql = "select * from test";
if(mysql_query(my,sql.c_str())) cout<<"mysql insert failed!"<<endl;
else cout<<"mysql insert successed!"<<endl;
mysql_close(my);
return 0;
}
发现实验结果确实如预想的那样。
但是有个问题!select语句在这里没有现象,需要配合其他函数使用。
注意:有些版本的mysql在远程连接使用的时候,插入数据有中文字符的时候,可能会出现乱码,我这里的版本是 8.0的,因此没有问题,不过如果插入的数据有乱码时,可以通过
int mysql_set_character_set(MYSQL* mysql, const char* csname)来设置字符集为utf8
mysql_store_result
针对select语句需要输出或者查看内容的情况,mysql提供该函数来将select 的数据从mysql句柄中提取到 MYSQL_RES 中,然后再输出。
MYSQL_RES 是一个MySQL的一种结构体,能够保存存储在 MYSQL 类型变量中的数据。
不过这个函数的返回值是一个指针,因此肯定在程序中开辟了一块空间,这块空间需要手动释放。
MySQL提供函数用于释放该指针
mysql_free_result()
该函数是专门用来释放MYSQL_RES指针的空间的。
如何查看MYSQL_RES中的数据
实际上MYSQL_RES和MYSQL类型一样,都是一个句柄。
因此是无法直接从MYSQL_RES中直接读取数据的,因此MySQL还提供了其他几个函数配合提取数据。
mysql_num_rows()
该函数能够从 MYSQL_RES 中提取数据的行数。
mysql_num_fields()
该函数能够从 MYSQL_RES 中提取数据的列数。
mysql_fetch_fields()
该函数能够一次性获取所有列名,其返回值类似于一个数组指针,想访问其内容可以采用访问数组指针内容的方式。
不过 MYSQL_FIELD 本身是一个类,想获取列名还需要知道该类有什么样的成员。
我们可以直接查看该类的成员结构。
其中列名分为列名和原列名,表明也是。这是因为select查询语句可以对列名进行重命名,因此会出现两个类似的变量。
mysql_fetch_row()
该函数能够获取结果内容,即每一行的内容。
而返回值的 MYSQL_ROW 类型实际上就是一个 char** 类型,因为接受的数据都是以字符串的形式接受的,因此想读取一行的数据,也是当作是一个二维数组来直接操作。
实验
我们写下如下的代码来实验是否能够得到 select 的数据。
#include<iostream>
#include<mysql/mysql.h>
#include<string>
using namespace std;
const string host = "localhost";
const string user = "lbx";
const string password = "124533lbxLBX..";
const string db = "rootDB";
const unsigned int port = 3306;
int main()
{
MYSQL * my;
my = mysql_init(nullptr);
if(my != NULL) cout<<"mysql init successed"<<endl;
else cout<<"muysql init failed!"<<endl;
if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0))
cout<<"mysql connect successed !"<<endl;
else cout<<"mysql connect failed !"<<endl;
// string sql = "insert into test (name,age) values ('张三',12)";
// string sqp = "delete from test where id = 2";
// string sql = "update test set name='jack' where id=1";
string sql = "select * from test";
if(mysql_query(my,sql.c_str())) cout<<"mysql select failed!"<<endl;
else cout<<"mysql select successed!"<<endl;
//将数据从my中提取到res中
MYSQL_RES* res = mysql_store_result(my);
//获取数据的行数
my_ulonglong row = mysql_num_rows(res);
//获取数据的列数
unsigned int col = mysql_num_fields(res);
//获取数据的名称
MYSQL_FIELD* file_name = mysql_fetch_fields(res);
//输出列名
for(int i = 0; i < col; i++)
{
cout<<file_name[i].name<<"\t";
}
cout<<endl;
MYSQL_ROW line;
for(int i = 0; i < row; i++)
{
//获取一行的数据
line = mysql_fetch_row(res);
// cout<<line[0]<<"\t"<<line[1]<<"\t"<<line[2]<<"\t";
for(int j = 0; j < col; j++)
{
cout<<line[j]<<"\t";
}
cout<<endl;
}
mysql_close(my);
return 0;
}
发现确实成功获得了数据。
此外。,有一个细节。
在这里,我们每次都是直接通过 mysql_fetch_row 来获取一行数据,没有说我们要获得哪一行的数据,但是结果却是正确的结果。
这是因为 res 就类似一个缓冲区,每通过 mysql_fetch_row 获取一行数据时,都会将提取出去的一行数据给删除,因此可以直接获取。
其他的函数
我们当然可以通过C语言链接来做类似于事务的操作。
首先我们可以通过 mysql_query() 来执行启动事务。
mysql_autocommit()
该函数用于启动事务。
这个函数可以开始事务是否自动提交。
我们可以通过 mode 参数来设置是否开启自动提交。
1 表示启动自动提交,0表示关闭自动提交。
mysql_commit()
当启动一个事务可以通过该函数直接提交。
0 表示提交成功,其他表示失败
mysql_rollback()
该函数能够回滚事务。
0表示回滚成功, 其他表示失败。
总结
本文总结了C/C++如何连接mysql,然后也介绍了连接的函数以及一些注意事项,也介绍了select时的特殊情况所用的函数,并进行了实践,希望对各位有所帮助。