LINUX下C/C++操作MySql

本文详细介绍了如何在C++中使用MySQL C库连接和操作数据库,包括安装库、创建数据库、执行SQL查询、处理结果集等步骤,并提供了一个C++封装的MyDB类示例代码,演示了连接、查询、插入和关闭数据库连接的过程。
摘要由CSDN通过智能技术生成

参考自: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

/*************************************************************************
    > File Name: mydb.h
    > Author:fengxin 
    > Mail:903087053@qq.com 
    > Created Time: 2017年07月21日 星期五 15时17分17秒
 ************************************************************************/

#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); //连接mysql
    bool exeSQL(string sql);   //执行sql语句
    private:
    MYSQL *mysql;          //连接mysql句柄指针
    MYSQL_RES *result;    //指向查询结果的指针
    MYSQL_ROW row;       //按行返回的查询信息
};


#endif

myDB.cpp:

/*************************************************************************
> File Name: MyDB.cpp
> Author:fengxin 
> Mail:903087053@qq.com 
> Created Time: 2017年07月21日 星期五 16时02分51秒
************************************************************************/

#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_real_connect建立一个数据库连接  
    // 成功返回MYSQL*连接句柄,失败返回NULL  
    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)
{
    //mysql_query()执行成功返回0,执行失败返回非0值。
    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  // result==NULL
        {
            if(mysql_field_count(mysql) == 0)   //代表执行的是update,insert,delete类的非查询语句
            {
                // (it was not a SELECT)
                int num_rows = mysql_affected_rows(mysql);  //返回update,insert,delete影响的行数
            }
            else // error
            {
                cout<<"Get result error: "<<mysql_error(mysql);
                return false;
            }
        }
    }

    return true;

}

下面是用于测试上面的测试代码
test.cpp:

/*************************************************************************
    > File Name: test.cpp
    > Author:fengxin 
    > Mail:903087053@qq.com 
    > Created Time: 2017年07月21日 星期五 16时43分55秒
 ************************************************************************/

#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

可以看到,上面我们执行sudo apt-get install libmysqlclient-dev安装的数据库开发库文件的路径是系统的默认路径,所以-L选项完全可以不加!(头文件也是被放到了系统头文件的默认路径!)

可以将选项-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

完全可以省略掉-L选项即:

g++  -o mydb test.cpp myDB.cpp  -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)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值