参考自:https://blog.csdn.net/fengxinlinux/article/details/75675360
一 安装
1)首先是再服务上安装mysql服务端和客户端,之前有相关记录 2)再次就是安装相关的C库:
sudo apt-get install libmysqlclient-dev
3) 在数据库中创建所使用到的数据库和表,必要时创建所需要的用户 这可以在mysql_client中操作: https://blog.csdn.net/luseysd/article/details/116716943
二 基本API
使用C库中提供的API来连接并操作数据库:
mysql_init() :获取或初始化MYSQL结构 mysql_real_connect() :连接到MySQL服务器。 mysql_query() :执行指定为“以Null终结的字符串”的SQL查询。 mysql_store_result():将查询的整个结果读取到客户端,分配一个MYSQL_RES结构,并将结果放入此结构中 mysql_use_result() :初始化逐行的结果集检索。 mysql_field_count():返回上次执行语句的结果集的列数。 mysql_num_fields():返回结果集中的列数(字段数)。 mysql_num_rows() :返回结果集中的行数。 mysql_fetch_row() :从结果集中获取下一行 mysql_free_result() :释放结果集空间
相关数据结构:
- MYSQL结构体
此结构表示一个数据库连接的处理程序。它几乎用于所有MySQL功能。 - MYSQL_RES结构体
存储查询结果数据。 - MYSQL_ROW结构体
存储一行数据的结构。
1) mysql_init()
函数原型:
MYSQL *mysql_init(MYSQL *mysql)
使用数据库第一步, 需要获取数据库的实例:
MYSQL *con = mysql_init(NULL);
那么, 所有的操作都必须围绕con进行执行. 这相当于一个连接对象.
2) mysql_real_connect()
之后, 需要建立一个链接, 指明数据库和用户: 函数原型:
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)
使用例子:
mysql_real_connect(m_SQLCON, "localhost", "user12", "34klq*",
"testdb", 0, NULL, CLIENT_MULTI_STATEMENTS);
指明用户和密码. 如果返回NULL, 则说明失败。
3)mysql_query()
其余的增删改查的语句, 都通过mysql_query执行. 具体直接参考下面的最终代码.
函数原型:
int mysql_query(MYSQL *mysql, const char *stmt_str);
MYSQL_RES *mysql_store_result(MYSQL *mysql);
unsigned int mysql_field_count(MYSQL *mysql);
unsigned int mysql_num_fields(MYSQL_RES *result);
my_ulonglong mysql_num_rows(MYSQL_RES *result) ;
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) ;
void mysql_free_result(MYSQL_RES *result);
注意一个地方, 每次执行完成语句后, mysql不是立刻提交, 这里面有事物的概念, 不在这里进行讨论. 需要说明的是, 如果一次进行多次操作, 需要单独进行语句提交操作, 代码格式如下:
3)基本步骤
1 使用mysql_init()初始化连接 2 使用mysql_real_connect()建立一个到mysql数据库的连接 3 使用mysql_query()执行查询语句 4 result = mysql_store_result(mysql)获取结果集 5 mysql_num_fields(result)获取查询的列数,mysql_num_rows(result)获取结果集的行数 6 通过mysql_fetch_row(result)不断获取下一行,然后循环输出 7 释放结果集所占内存mysql_free_result(result) 8 mysql_close(conn)关闭连接
4)C++ 使用例子
C++封装: myDB.h
#ifndef _MYDB_H
#define _MYDB_H
#include<iostream>
#include<string>
#include<mysql/mysql.h>
using namespace std;
class MyDB
{
public:
MyDB();
~MyDB();
bool initDB(string host,string user,string pwd,string db_name);
bool exeSQL(string sql);
private:
MYSQL *mysql;
MYSQL_RES *result;
MYSQL_ROW row;
};
#endif
myDB.cpp:
#include<iostream>
#include<string>
#include "MyDB.h"
using namespace std;
MyDB::MyDB()
{
mysql=mysql_init(NULL);
if(mysql==NULL)
{
cout<<"Error:"<<mysql_error(mysql);
exit(1);
}
}
MyDB::~MyDB()
{
if(mysql!=NULL)
{
mysql_close(mysql);
}
}
bool MyDB::initDB(string host,string user,string passwd,string db_name)
{
mysql = mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(), db_name.c_str(), 0, NULL, 0);
if(mysql == NULL)
{
cout << "Error: " << mysql_error(mysql);
exit(1);
}
return true;
}
bool MyDB::exeSQL(string sql)
{
if (mysql_query(mysql,sql.c_str()))
{
cout<<"Query Error: "<<mysql_error(mysql);
return false;
}
else
{
result = mysql_store_result(mysql);
if (result)
{
int num_fields = mysql_num_fields(result);
int num_rows=mysql_num_rows(result);
for(int i=0;i<num_rows;i++)
{
row=mysql_fetch_row(result);
if(row<0) break;
for(int j=0;j<num_fields;j++)
{
cout<<row[j]<<"\t\t";
}
cout<<endl;
}
}
else
{
if(mysql_field_count(mysql) == 0)
{
int num_rows = mysql_affected_rows(mysql);
}
else
{
cout<<"Get result error: "<<mysql_error(mysql);
return false;
}
}
}
return true;
}
下面是用于测试上面的测试代码 test.cpp:
#include<iostream>
#include"MyDB.h"
using namespace std;
int main()
{
MyDB db;
db.initDB("localhost","liuzhen","mima","test");
db.exeSQL("INSERT accounts values('fengxin','123');");
db.exeSQL("INSERT accounts values('axin','456');");
db.exeSQL("SELECT * from accounts;");
return 0;
}
测试的例子是,创建一个test数据库,向数据库里的记录用户帐号密码的accounts表中添加和查询数据。
首先,我们在终端下登录数据库,创建一个test数据库,并创建一个名为accounts的表。
mysql -u root -p
Enter password:
Welcome to the MySQL monitor.
mysql>create database test;
Query OK, 1 row affected (0.00 sec)
mysql>use test;
Database changed
mysql>create table accounts(name char(20) not null primary key,passwd char(20) not null);
Query OK, 0 rows affected (0.52 sec)
mysql>exit;
然后编译上面的代码,编译的时候,要加上:mysql_config --cflags --libs 才能编译通过。
例如:
g++ MyDB.cpp test.cpp -o test mysql_config --cflags --libs
接下来是便编译,这里需要注意的是,要链接需要的库libmysqlclient.so,终端输入命令mysql_config --libs:
ubuntu@VM-0-7-ubuntu:~/webserver$ mysql_config --libs
-L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -lm -lrt -latomic -lssl -lcrypto -ldl
将选项-L/usr/lib/x86_64-linux-gnu -lmysqlclient加入gcc/g++命令中,或makefile中,即:
g++ -o mydb test.cpp myDB.cpp -L/usr/lib/x86_64-linux-gnu -lmysqlclient
编译通过后,运行得到:
ubuntu@VM-0-7-ubuntu:~/webserver$ ./test
axin 456
fengxin 123
通过终端连接数据库查看accounts表的内容,我们看到的结果也是一样的。
mysql> select * from accounts;
+
| name | passwd |
+
| axin | 456 |
| fengxin | 123 |
+
2 rows in set (0.00 sec)
|