没腿的鸟 发表于 7 天前

MySQL·C/C++访问数据库

目录
准备工作
测试是否安装成功
C/C++语言访问
官方文档
接口介绍利用
mysql_init()
mysql_close() 
增补1:makefile编写
mysql_real_connect() 
测试1:编译链接
mysql_query()
测试2:SQL语句测试
改 



错误1:SQL语句错误
错误2:编码错误
mysql_set_character_set()
测试3:编码错误测试
查询的后序处置处罚
mysql_store_result()
mysql_num_rows() 
mysql_num_fields()
测试4:行列获取测试
mysql_fetch_row()
测试5:读取数据测试
mysql_fetch_fields()
测试6:读取数据测试
mysql_free_result()
增补2:事务
全部的测试代码

准备工作

起首我们创建一个用户 参考上文MySQL·用户管理-CSDN博客

https://i-blog.csdnimg.cn/direct/9581840d7e714893b20b538edf65b4bc.png
赋予权限
https://i-blog.csdnimg.cn/direct/c0f73ecdbd36405f8545e2c5155e7be7.png
登入与权限测试
https://i-blog.csdnimg.cn/direct/111a777420834bcbaf61b11305fb90d6.png
方法一:动静态链接 
C库下载
   链接:MySQL :: MySQL Community Downloads
https://i-blog.csdnimg.cn/direct/91bf7156db75473a9e55d784a806adc1.png
找到C版本支持的第三方库下载对应版本即可
方法二:yum源直接安装
参考下文: 
   MySQL卸载、安装、登入与配置_yum 卸载mysql-CSDN博客
曾经安装过了,就不再演示了 
https://i-blog.csdnimg.cn/direct/b5bfc96e6f014470bf15b35ef2d49322.png
https://i-blog.csdnimg.cn/direct/ba042d81f526493fb9dd999753c6c1a8.png
假如还是没有可以尝试直接安装
yum install mysql-devel 假如是一起看过来的话,可能你们的yum源必要更新了,我利用的源现在是有一些是无法访问的,但是到现在还没有什么影响,以是为了防止出现意外,就继续利用了。具体错误如下
https://i-blog.csdnimg.cn/direct/374902f6ab5547bd951f3b1bfb692005.png

测试是否安装成功

这是一个返回MySQL版本的一个函数,我们可以用它来做测试 
#include <iostream>
#include <mysql/mysql.h>

int main()
{
    std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
    return 0;
}  直接编译是无法成功的,我们必要指定动态库
https://i-blog.csdnimg.cn/direct/8bd0e257732540df993974c9e27ad312.png
https://i-blog.csdnimg.cn/direct/a87c4f38ccff432b8cb628d54a41aa10.png
只指明库名也是无法成功的,我们还必要添加路径
https://i-blog.csdnimg.cn/direct/bc95bff7606f4da4aad1be9473c8f7a8.png
g++ -o mytest test.cc -L/lib64/mysql/ -lmysqlclient 如许我们发现编译成功了,而且成功返回了MySQL的版本号
https://i-blog.csdnimg.cn/direct/229467dd84eb4cf5b3883eb550971db9.png
没有找到可以是由于这个的指明是无法找到,必要重新配置环境
https://i-blog.csdnimg.cn/direct/e217555980104481916477a37820ae68.png
你可能必要把环境添加到这里面来 
https://i-blog.csdnimg.cn/direct/a9c35481259141fea7110aed558ac86e.png
通常环境下,MySQL的安装程序会自动配置好所需的环境变量和库路径,你可能不必要手动进行这些操作。
解决方法可以参考下面这里的答复
https://i-blog.csdnimg.cn/direct/ff8593abf7ac46f8a2980ad5c50a529c.png
假如在头文件中不指明文件夹的话,则必要在编译指令中添加文件夹
#include <iostream>
#include <mysql.h>

int main()
{
    std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
    return 0;
} 直接编译会报错 
https://i-blog.csdnimg.cn/direct/c5be61c4fb5b468fbede2879bc89ec86.png
添加大 -I 选项 
https://i-blog.csdnimg.cn/direct/7013c1029abc4b4eb3f401e5d5faad81.png
C/C++语言访问

官方文档

   MySQL :: MySQL Documentation
找到C的,对应版本 
https://i-blog.csdnimg.cn/direct/1183c25299cb4e7c8fd31d465c94bb23.png 
   官方接口 :MySQL :: MySQL 5.7 C API Developer Guide :: 4 C API Function Reference
https://i-blog.csdnimg.cn/direct/426b7ed7044041b195eb31e0c3b378bc.png
接口介绍利用

mysql_init()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.37 mysql_init()
创建一个mysql类的布局体
https://i-blog.csdnimg.cn/direct/4245b94e93834f67b9645b297d974d59.png
MySQL类里面就是一些信息
https://i-blog.csdnimg.cn/direct/8c4371cf87f9473e93b9977fd03c128a.png
mysql_close() 

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.5 mysql_close()
关闭释放这个句柄 
https://i-blog.csdnimg.cn/direct/7f0aa8f9d20b4167adfbe829c27aed91.png
创建而且关闭 
#include <iostream>
#include <mysql/mysql.h>

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }

    // 关闭释放该句柄
    mysql_close(my);
    return 0;
}  
编译测试 
https://i-blog.csdnimg.cn/direct/a56dbc45077d4f0598738cf97602cca4.png
增补1:makefile编写

mytest:test.cc
        g++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient
.PHONY:clean
clean:
        rm -f mytest
#上面的原式 g++ -o mytest test.cc -std=c++11 -L/lib64/mysql -lmysqlclient
#其中$@ $^表示自动变量,前者表示目标项,后者表示全部依赖项,$<表示第一个依赖项 mysql_real_connect() 

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.54 mysql_real_connect() 
链接数据库 
https://i-blog.csdnimg.cn/direct/d7360267ecf641e18dbd1e78c01f7e96.png
#include <iostream>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
}  
测试1:编译链接

https://i-blog.csdnimg.cn/direct/c976b1ca064245b293cc9f4881154885.png  
为了方便演示,我们先创建一张表
create table user(
    id bigint primary key auto_increment,
    name varchar(32) not null,
    age int not null,
    telphone varchar(32) unique
    );
https://i-blog.csdnimg.cn/direct/13acd9f055cc4a2cb669a6ce092c0657.png
显然这里是没有什么题目标
我们可以通过下面这条SQL语句检察当前链接的用户信息 
show processlist;
https://i-blog.csdnimg.cn/direct/a7a7420535ab436b9571e82f4e0abfa6.png 
我们对代码进行修改,让它不要这么快退出,让我们看到链接的信息
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    sleep(10);
    std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} 这一次我们看到了 
https://i-blog.csdnimg.cn/direct/07f5213fb44d4c5185670b35abcf18e3.png
显然现在没有出现什么错误
mysql_query()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.53 mysql_query()
下达指令 
https://i-blog.csdnimg.cn/direct/c7348da405eb473fa1cc45dd52f98d73.png

#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
}  
测试2:SQL语句测试

https://i-blog.csdnimg.cn/direct/fa37861a51a14b97920d8f11e82db00d.png
改 

不外实在我们并不必要这么麻烦去写一个MySQL的客户端,我们只必要利用即可
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    std::string sql = "update user set name='Jimmy' where id=2";
    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else std::cerr << sql << " failed: " << n << std::endl;
    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} https://i-blog.csdnimg.cn/direct/8e671b019a24404d97a0da0e97b70560.png
显然这里是没有出现什么错误的,我们能够利用语言来实现对数据的控制
下面进行增删改查测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=1";
    std::string sql = "select * from user";

    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else std::cerr << sql << " failed: " << n << std::endl;
    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} 增

https://i-blog.csdnimg.cn/direct/f84b3abddc684c4daefd465d7a4fab86.png


https://i-blog.csdnimg.cn/direct/c2546e4a92f9413cb86b594ebfc6784f.png


我们会发现查这个操作是无法进行的,由于查是这四种操作最欠好处置处罚的,由于这个消息并不是让服务端去表现,在利用的时候,我们肯定是要让用户去看到这个查的消息,这个我们在后面进行详细介绍
https://i-blog.csdnimg.cn/direct/b6cf33c433b54b32a41d046a6d69ccdc.png

 
错误1:SQL语句错误

从这里看到,当用户传递的SQL语句不正确的时候,MySQL的服务端是不会进行处置处罚的,当然这也是我们可以预料到的,由于MySQL包管对数据的操作,只要是成功的,就一定是正确的SQL语句,反之假如失败的,就一定是错误的语句
https://i-blog.csdnimg.cn/direct/93887272e7004c44ba9825d5bf657eb5.png
错误2:编码错误

我们可以看到,这里插入中文的话,是会出现乱码的,但是我们知道的,在一开始我们就已经配置好了MySQL的编码格式,那么为什么这里还是会出现呢?
https://i-blog.csdnimg.cn/direct/cb0ee05a94794a1982384b20e3255f3d.png
如下我们配置里面是利用的utf8的
https://i-blog.csdnimg.cn/direct/3cdb405cef42453584d4e2d6dcf1977c.png
        这实在是由于编码的不同等导致的,建立好链接之后,获取英文没有题目,假如获取中文是乱码:设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.69 mysql_set_character_set()
设置编码格式
测试3:编码错误测试

#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    mysql_set_character_set(my, "utf8");

    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=1";
    // std::string sql = "select * from user";
    std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";

    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else std::cerr << sql << " failed: " << n << std::endl;
    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} 这下插入就没有编码不同等带来的乱码了
https://i-blog.csdnimg.cn/direct/ba899d199adc4d658daacc7b9f236ad4.png

查询的后序处置处罚

mysql_store_result()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.77 mysql_store_result()
把查询到的结果转存到某个地方,MYSQL_RES
https://i-blog.csdnimg.cn/direct/0311667dffeb47988f0733442b93217b.png

MYSQL_RES的内容实在就是一个布局体
https://i-blog.csdnimg.cn/direct/ee8edb51b5a646d98d4da19903f9628f.png
mysql_num_rows() 

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.49 mysql_num_rows()
拿取行 
https://i-blog.csdnimg.cn/direct/8cff62a6d60c4915b6abb09b70dc2f5a.png

mysql_num_fields()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.48 mysql_num_fields()
拿取列 
https://i-blog.csdnimg.cn/direct/6d9d1dba87704b47ad3626d575186528.png 
此中 my_ulonglong 实在就是 unsigned long long 范例的数据
https://i-blog.csdnimg.cn/direct/fbe8e4c0de56412b875468a0bbbbe194.png 
测试4:行列获取测试

#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    mysql_set_character_set(my, "utf8");

    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=4";
    // std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";

    std::string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else
    {
      std::cerr << sql << " failed: " << n << std::endl;
      return 3;
    }
    MYSQL_RES *res = mysql_store_result(my);
    if(nullptr == res)
    {
      std::cerr << "mysql_store_result error" << std::endl;
      return 4;
    }

    my_ulonglong rows = mysql_num_rows(res); // 拿取行
    my_ulonglong fields = mysql_num_fields(res); // 拿取列

    std::cout << "行: " << rows << std::endl;
    std::cout << "列: " << fields << std::endl;

    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} 看到结果,我们确实拿到了具体的行和列 
https://i-blog.csdnimg.cn/direct/81578aa3b43a4f06be98c261c736a5c1.png
当我们测试拿取一条数据的时候,也是正确的,用where进行筛选
https://i-blog.csdnimg.cn/direct/1d6d5055741b44c39ddcb63655f3bd6c.png
https://i-blog.csdnimg.cn/direct/fe86502373954fcb95c0f082eaacadd0.png

mysql_fetch_row()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.21 mysql_fetch_row()
自动迭代遍历,获取数据
https://i-blog.csdnimg.cn/direct/a4a7b9064e9e4596a81fb9554e889132.png
https://i-blog.csdnimg.cn/direct/fcf04aff3c574c4abda4297b83a537fe.png
一个新的宏,MYSQL_ROW ,实在就是一个指针,我们将其看做一个指向一个二维数组的指针就行了
https://i-blog.csdnimg.cn/direct/e19174fad01341bb8c9f5be18e786d58.png
测试5:读取数据测试

#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    mysql_set_character_set(my, "utf8");

    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=4";
    // std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
    // std::string sql = "select * from user where id=3";
    std::string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else
    {
      std::cerr << sql << " failed: " << n << std::endl;
      return 3;
    }
    MYSQL_RES *res = mysql_store_result(my);
    if(nullptr == res)
    {
      std::cerr << "mysql_store_result error" << std::endl;
      return 4;
    }

    // 到这里都是和结果集有关的,MYSQL_RES
    my_ulonglong rows = mysql_num_rows(res); // 拿取行
    my_ulonglong fields = mysql_num_fields(res); // 拿取列

    std::cout << "行: " << rows << std::endl;
    std::cout << "列: " << fields << std::endl;

    // 将其当作一个二维数组去遍历即可
    for(my_ulonglong i = 0; i < rows; ++i)
    {
       MYSQL_ROW row = mysql_fetch_row(res);    // 和迭代器很像,会自己维护一个指针,自动遍历
       for(my_ulonglong j = 0; j < fields; ++j)
       {
            std::cout << row << "\t"; // *(row+j) 其实就是解引用
       }
       std::cout << std::endl;
    }

    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} 可以看到我们拿取到了结果,而且没有错误
https://i-blog.csdnimg.cn/direct/cb15c164cdd74816a05c5109535b3f82.png

mysql_fetch_fields()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.19 mysql_fetch_fields()
获取列名信息 
https://i-blog.csdnimg.cn/direct/67fd118d822547619093166aed4cbcfa.png 
MYSQL_FIELD
https://i-blog.csdnimg.cn/direct/42956b15a9bc444586415d819b306943.png
https://i-blog.csdnimg.cn/direct/34aa0e5b5090477abc90987a812d1c99.png
这里是不是很熟悉,这里就是MySQL里面的那一套 
https://i-blog.csdnimg.cn/direct/f12dffa412b94d87aabdaee9d3e1ca9d.png 
 
测试6:读取数据测试


#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    mysql_set_character_set(my, "utf8");

    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=4";
    // std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
    // std::string sql = "select * from user where id=3";
    std::string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else
    {
      std::cerr << sql << " failed: " << n << std::endl;
      return 3;
    }
    MYSQL_RES *res = mysql_store_result(my);
    if(nullptr == res)
    {
      std::cerr << "mysql_store_result error" << std::endl;
      return 4;
    }

    // 到这里都是和结果集有关的,MYSQL_RES
    my_ulonglong rows = mysql_num_rows(res); // 拿取行
    my_ulonglong fields = mysql_num_fields(res); // 拿取列

    std::cout << "行: " << rows << std::endl;
    std::cout << "列: " << fields << std::endl;

    // 将其当作一个二维数组去遍历即可
    // 读取属性
    MYSQL_FIELD *fields_arry = mysql_fetch_fields(res);
    for(my_ulonglong i = 0; i < fields; i++)
    {
      std::cout << fields_arry.name << "\t";
    }
    std::cout << "\n";

    // 读取内容
    for(my_ulonglong i = 0; i < rows; ++i)
    {
       MYSQL_ROW row = mysql_fetch_row(res);    // 和迭代器很像,会自己维护一个指针,自动遍历
       for(my_ulonglong j = 0; j < fields; ++j)
       {
            std::cout << row << "\t"; // *(row+j) 其实就是解引用
       }
       std::cout << std::endl;
    }

    // 读取数据库名,表名
    std::cout << fields_arry.db << " " << fields_arry.table << std::endl;

    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_close(my);
    return 0;
} https://i-blog.csdnimg.cn/direct/175e549304704277b8a40b206b98a916.png
我们可以看到,实在MySQL的客户端本质上就是对这些数据进行处置处罚,本身就是看做对字符串的处置处罚,原理很简单
mysql_free_result()

MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.25 mysql_free_result()
释放结果集 
https://i-blog.csdnimg.cn/direct/e51aa8608a49429d8735b7f03e81861e.png
官方提供了专门用来释放结果集的函数
https://i-blog.csdnimg.cn/direct/57706d58bc004a588a4cfc3c49e70882.png
利用起来也很简单,就像C++里面的free函数一样就行 
mysql_free_result(res);
增补2:事务

我们都知道每一次的单SQL语句在MySQL看来都是一个事务,以是我们这里并没有测试事务的启动和提交,我们知道这一点就行了,通常我们会把一堆SQL语句放一起提交,那么MySQL就会把它当成一个事务,以是我们在代码上一样平常也不怎么讨论事务的启动和提交,当然了我们也可以开启事务,MySQL也提供了相应的函数好比下面这几个
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql); 实在我们也可以用mysql_query()这个提交来开启事务,好比提交begin,commit,rollback都能够实现,看自己需求

全部的测试代码

#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>

// const std::string host = "127.0.0.1";
const std::string host = "localhost";   // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;

int main()
{
    // std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;

    // 创建一个mysql句柄
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
      std::cerr << "init MySQL error" << std::endl;
      return 1;
    }
    if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
      std::cerr << "connect MySQL error" << std::endl;
      return 2;
    }
    mysql_set_character_set(my, "utf8");

    // std::string sql = "update user set name='Jimmy' where id=2"; // 改
    // std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
    // std::string sql = "delete from user where id=4";
    // std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
    // std::string sql = "select * from user where id=3";
    std::string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if(n == 0) std::cout << sql << " success: " << n << std::endl;
    else
    {
      std::cerr << sql << " failed: " << n << std::endl;
      return 3;
    }
    MYSQL_RES *res = mysql_store_result(my);
    if(nullptr == res)
    {
      std::cerr << "mysql_store_result error" << std::endl;
      return 4;
    }

    // 到这里都是和结果集有关的,MYSQL_RES
    my_ulonglong rows = mysql_num_rows(res); // 拿取行
    my_ulonglong fields = mysql_num_fields(res); // 拿取列

    std::cout << "行: " << rows << std::endl;
    std::cout << "列: " << fields << std::endl;

    // 将其当作一个二维数组去遍历即可
    // 读取属性
    MYSQL_FIELD *fields_arry = mysql_fetch_fields(res);
    for(my_ulonglong i = 0; i < fields; i++)
    {
      std::cout << fields_arry.name << "\t";
    }
    std::cout << "\n";

    // 读取内容
    for(my_ulonglong i = 0; i < rows; ++i)
    {
       MYSQL_ROW row = mysql_fetch_row(res);    // 和迭代器很像,会自己维护一个指针,自动遍历
       for(my_ulonglong j = 0; j < fields; ++j)
       {
            std::cout << row << "\t"; // *(row+j) 其实就是解引用
       }
       std::cout << std::endl;
    }

    // 读取数据库名,表名
    std::cout << fields_arry.db << " " << fields_arry.table << std::endl;

    /*
    // 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
    std::string sql;
    while(true)
    {
      std::cout << "MySQL>>> ";
      if(!std::getline(std::cin, sql) || sql == "quit")
      {
            std::cout << "bye bye" << std::endl;
            break;
      }
      int n = mysql_query(my, sql.c_str());
      if(n == 0)
      {
            std::cout << sql << " success: " << n << std::endl;
      }
      else
      {
            std::cerr << sql << " failed: " << n << std::endl;
      }
    }
    */
    // sleep(10);
    // std::cout << "connnect success" << std::endl;
    // 关闭释放该句柄
    mysql_free_result(res);
    mysql_close(my);
    return 0;
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MySQL·C/C++访问数据库