MySQL--C_C++语言连接访问

Connector/C的使用

首先需要在mysql官网下载C接口库

解压指令

tar -zxvf 压缩包名

下载并解压好后

 但是还有比这更优的做法。

这样子手动安装不仅麻烦,还可能存在兼容性的问题。

其实在我们使用yum安装mysql时,大概率会自动帮我们把其他的环境都安装下来并配置好

sudo yum install -y mysql-community-server

如果没有安装好,那么我们也可以单独安装

yum install myslq-devel

安装好后,查看

ls /usr/include/mysql

可以看到头文件就都在默认的搜索目录下了

那么我们就可以开始写代码了,注意包含头文件的方式

简单使用 

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

int main()
{
    printf("mysql client Version: %s\n", mysql_get_client_info());
    return 0;
}

makefile

test:test.cc
	g++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient

.PHONY:clean

clean:
	rm -f test

编译指令记得指明库所在的位置以及指明需要链接哪个库 

-I(大写的i),在编译时可以告诉g++我们的头文件位置在哪里,这样的话我们包头文件可以直接包。

运行结果

ldd ./test

 可以查看这个程序链接了那些库

用C_C++进行增删改

首先我们需要创建一个MYSQL对象,并对它进行初始化,并在不用的时候记得释放。 

然后因为mysql是网络服务(基于TCP/IP的)。因此我们需要先链接

链接接口的使用:

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 clientflag);

//后两个字段可以设置为nullptr和0

//建立好链接之后,获取英文没有问题,如果获取中文是乱码:
//设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");

示例:

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

const std::string host = "127.0.0.1";
const std::string user = "chika";
const std::string password = "3412741074";
const std::string db = "test_db";
const int port = 3306;

int main()
{
    //printf("mysql client Version: %s\n", mysql_get_client_info());
    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(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "mysql connect error" << std::endl;
        return 2;
    }

    std::cout<< "mysql connect success" << std::endl;
    sleep(5);

    mysql_close(my);
    return 0;
}

记得事先将自己的mysql服务启动。另外ip地址我们用的是本地环回地址,如果是本地链接,也可以改为 "localhost" 。

在mysql这边,我们可以用

show processlist;

来查看当前mysql的链接情况。

 首先我们先在本地mysql上创建一张测试表

create table test(
    id int primary key auto_increment,
    name varchar(25) not null,
    qq varchar(30)
    );

 mysql_query()可以向mysql使其执行增删改查操作。

int mysql_query(MYSQL *mysql, const char *query);

第一个参数就是我们创建的mysql对象,第二个参数就是我们将要执行的命令。并且,这个命名是可以不带 ; 的。

成功返回0,失败返回非0值。

比如我们插入一条数据

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

const std::string host = "127.0.0.1";
const std::string user = "chika";
const std::string password = "3412741074";
const std::string db = "test_db";
const int port = 3306;

int main()
{
    //printf("mysql client Version: %s\n", mysql_get_client_info());
    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(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "mysql connect error" << std::endl;
        return 2;
    }
    //设置好utf8编码,防止中文乱码
    mysql_set_character_set(my, "utf8");
    
    std::string sql = "insert into test1 (name,qq) values('李三光','123456')";
    int n = mysql_query(my,sql.c_str());
    if(n == 0) std::cout << "success" << std::endl;
    else std::cout << "sql error" << std::endl;

    mysql_close(my);
    return 0;
}

makefile

test:test.cc
	g++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient

.PHONY:clean
clean:
	rm -f test

 编译并执行后

 此时看看表中的数据

 发现成功的插入进来了。

那么删除和修改也是同一个道理,就不重复演示了。

另外增删改是最简单的,因为我们只需要看到执行结果就可以了。但是查询是最复杂的,我们不仅要确保执行成功,还要将结果打印出来,处理比较麻烦。 

查询的细节 

前面说了,我们查询的话,还需要将结果打印出来,那么这个结果其实是保存在第一个参数,也就是那个结构体里面的。

此时还需要用到一个函数

mysql_store_result() 

如果 mysql_query 返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:
MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数会调用 MYSQL 变量中的 st_mysql_methods 中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数 malloc 了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result), 不然是肯定会造成内存泄漏的。 执行完mysql_store_result 以后,其实数据都已经在 MYSQL_RES 变量中了,下面的 api 基本就是读取MYSQL_RES 中的数据。

获取结果行数mysql_num_rows

my_ulonglong mysql_num_rows(MYSQL_RES *res);

 获取结果列数mysql_num_fields

unsigned int mysql_num_fields(MYSQL_RES *res);

 获取列名mysql_fetch_fields

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

 示例:
 

int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
int i = 0;
for(; i < fields; i++){
cout<<field[i].name<<" ";
}
cout<<endl;

接着就是要获取表的内容信息,并打印出来

获取结果内容 mysql_fetch_row
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

 它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char **.就当成一个二维数组来用吧。

示例: 

i = 0;
MYSQL_ROW line;
for(; i < nums; i++){
line = mysql_fetch_row(res);
int j = 0;
for(; j < fields; j++){
cout<<line[j]<<" ";
}
cout<<endl;
}

在mysql中,我们每次查询出来的结果都是一个表结构,但这其实是被处理过后的结果。每次查询,mysql会先将所有的数据读取出来后,转化成字符串。

所以MYSQL_RES可以想象成一个三维数组,没一行代表的是表中的每一行信息。

每一个元素就是一个char**,它们又指向了char*,char*则最终指向了该表中某行某列的结果。 

 这个是跟表的内容相关的。

MYSQL_FIELD跟表的属性相关,它也是一个结构体。

在我们使用完了这个结果集之后,记得将其free掉。

mysql_free_result()函数就是这些API函数之一,其主要用途是释放一个MYSQL_RES结构所占用的内存。

void mysql_free_result(MYSQL_RES *result);

 浅谈一下mysql连接池

 我们知道mysql是网络服务,那么其他客户端想让mysql执行命令时需要先进行链接,为了提高效率,我们可以创建一个连接池,连接池里面有多个线程,每一个线程管理着一个mysql对象(已连接好mysqld的),然后循环等待任务。然后用户想进行操作时,就只需要打包一个task任务结构体,交给连接池,连接池把这个任务放在队列里面,让空闲的线程取走,把里面的sql交给musql执行。就是生产者消费者模型。这样就避免了每次sql都要重新建立链接的操作。

  另外关于查询,在task结构体里面可以设置一个回调函数,如果这是一个查询sql,那么可以通过这个回调函数把结果拿回来,这个回调函数是由用户这边设置好的。

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值