【MySQL】使用C语言链接

【MySQL】使用C语言链接

🌈 个人主页:Zfox_
🔥 系列专栏:MySQL

目录

一:🔥 MySQL connect

📚 MySQL 的基础,我们之前已经学过,后面我们只关心使用
要使用 C 语言连接 MySQL,需要使用 MySQL 官网提供的库,大家可以去官网下载
我们使用 C接口库来进行连接
要正确使用,我们需要做一些准备工作:
保证 mysql 服务有效在官网上下载合适自己平台的 MySQL connect 库,以备后用建议直接使用命令 sudo yum install -y mysql-community-server 安装

🦋 Connector / C 使用

  • 📚 我们下下来的库格式如下:
#tree/usr/include/mysql/usr/include/mysql ├── client_plugin.h ├── errmsg.h ├── field_types.h ├── my_command.h ├── my_compress.h ├── my_list.h ├── mysql_com.h ├── mysqld_error.h ├── mysql.h ├── mysql_time.h ├── mysql_version.h ├── mysqlx_ername.h ├── mysqlx_error.h ├── mysqlx_version.h ├── plugin_auth_common.h └── udf_registration_types.h lib #find/usr -name "libmysqlclient*"/usr/share/doc/libmysqlclient21 /usr/share/doc/libmysqlclient-dev /usr/lib/x86_64-linux-gnu/libmysqlclient.so.21.2.40/usr/lib/x86_64-linux-gnu/libmysqlclient.a /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient.so.21

📚 其中 include 包含所有的方法声明, lib 包含所有的方法实现(打包成库)

尝试链接 mysql client

通过 mysql_get_client_info() 函数,来验证我们的引入是否成功
#include<iostream>#include<mysql/mysql.h>intmain(){ std::cout <<"mysql client version: "<<mysql_get_client_info()<< std::endl;return0;} $ g++-o mytest test.cc -std=c++11-lmysqlclient $ ls Makefile mytest test.cc $ ./mytest mysql client version:8.0.40

至此引入库的工作已经做完,接下来就是熟悉接口

🦋 mysql 接口介绍

🦁 MySQL官方文档借口介绍

在这里插入图片描述
初始化 mysql_init()

要使用库,必须先进行初始化!

初始化一个 MYSQL对象 MYSQL *mysql_init(MYSQL *mysql); 使用 mysql_init函数初始化一个 MySQL 连接句柄,为后续操作做准备。 如: MYSQL *mfp =mysql_init(NULL)
链接数据库 mysql_real_connect

📚 初始化完毕之后,必须先链接数据库,在进行后续操作。(mysql网络部分是基于TCP / IP的)

MYSQL *mysql_real_connect(MYSQL *mysql,constchar*host,constchar*user,constchar*passwd,constchar*db,unsignedint port,constchar*unix_socket,unsignedlong clientflag);//建立好链接之后,获取英文没有问题,如果获取中文是乱码://设置链接的默认字符集是utf8,原始默认是latin1mysql_set_character_set(myfd,"utf8");

第一个参数 MYSQL是 C api 中一个非常重要的对象(mysql_init的返回值),里面内存非常丰富,有
port, dbname, charset 等连接基本参数。它也包含了一个叫 st_mysql_methods 的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
mysql_real_connect 函数中各参数,基本都是顾名思意。

📚 测试:

#include<iostream>#include<unistd.h>#include<string>#include<mysql/mysql.h>const std::string host ="127.0.0.1";const std::string user ="connector";const std::string passwd ="123456";const std::string db ="conn";constunsignedint port =3306;intmain(){ std::cout <<"mysql client version: "<<mysql_get_client_info()<< std::endl; MYSQL* my =mysql_init(nullptr);if(my ==nullptr){ std::cerr <<"init MySQL error"<< std::endl;return1;}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;return2;} std::cout <<"connect success"<< std::endl;mysql_set_character_set(my,"utf8");// 设置字符集mysql_close(my);return0;}

📚 结果:

# ./mytest mysql client version:8.0.40 connect success 

下发 mysql 命令 mysql_query

intmysql_query(MYSQL *mysql,constchar*q);

第一个参数上面已经介绍过,第二个参数为要执行的sql语句,如“select * from table”。
获取执行结果 mysql_store_result sql 执行完以后,如果是查询语句,我们当然还要读取数据,如果 update,insert 等语句,那么就看下操作成功与否即可。

#include<iostream>#include<unistd.h>#include<string>#include<mysql/mysql.h>const std::string host ="127.0.0.1";const std::string user ="connector";const std::string passwd ="123456";const std::string db ="conn";constunsignedint port =3306;intmain(){ std::cout <<"mysql client version: "<<mysql_get_client_info()<< std::endl; MYSQL* my =mysql_init(nullptr);if(my ==nullptr){ std::cerr <<"init MySQL error"<< std::endl;return1;}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;return2;} std::cout <<"connect success"<< std::endl;mysql_set_character_set(my,"utf8");// 设置字符集 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;}}mysql_close(my);return0;}

我们来看看如何获取查询结果: 如果 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
获取结果列数 mysql_num_fields
获取列名 mysql_fetch_fields
如:

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

获取结果内容mysql_fetch_row
它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char **. 就当成一个二维数组来用吧

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

🦋 完整代码样例

#include<iostream>#include<unistd.h>#include<string>#include<mysql/mysql.h>const std::string host ="127.0.0.1";const std::string user ="connector";const std::string passwd ="123456";const std::string db ="conn";constunsignedint port =3306;intmain(){ std::cout <<"mysql client version: "<<mysql_get_client_info()<< std::endl; MYSQL* my =mysql_init(nullptr);if(my ==nullptr){ std::cerr <<"init MySQL error"<< std::endl;return1;}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;return2;} std::cout <<"connect success"<< std::endl;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, 6543219876)"; std::string sql ="select * from user";int n =mysql_query(my, sql.c_str());if(n ==0) std::cout << sql <<" success"<< std::endl;else{ std::cerr << sql <<" failed"<< std::endl;return3;} MYSQL_RES *res =mysql_store_result(my);if(res ==nullptr){ std::cerr <<"mysql_store_result error"<< std::endl;return4;} 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_array =mysql_fetch_fields(res);for(int i =0; i < fields; i++){ std::cout << fields_array[i].name <<'\t';} std::cout <<'\n';// 内容for(int i =0; i < rows; i++){ MYSQL_ROW row =mysql_fetch_row(res);// mysql_fetch_row相当于一个迭代器,会自动向后遍历 MYSQL_ROW 就是一个 char** 的二级指针for(int j =0; j < fields; j++){ std::cout << row[j]<<'\t';} std::cout <<'\n';}mysql_free_result(res);mysql_close(my);return0;}

📚 关闭 mysql 链接 mysql_close

voidmysql_close(MYSQL *sock);

📚 另外,mysql C api 还支持事务等常用操作,大家下来自行了解:

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

或者直接通过query函数直接操作都可以

二:🔥 共勉

以上就是我对 【MySQL】使用C语言链接 的理解,觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~😉

Read more

【C++】如何快速实现一棵支持key或key-value的二叉搜索树?关键技巧一文掌握!

【C++】如何快速实现一棵支持key或key-value的二叉搜索树?关键技巧一文掌握!

🎬 个人主页:MSTcheng · ZEEKLOG 🌱 代码仓库 :MSTcheng · Gitee 🔥 精选专栏: 《C语言》 《数据结构》 《C++由浅入深》 💬座右铭:路虽远行则将至,事虽难做则必成! 前言:在前面的文章中我们向大家介绍了一些序列式容器,比如:basic_string、vector、deque、list等。而本篇文章我们将要进入树形容器——二叉搜索树的学习。 文章目录 * 一、二叉搜索树的认识 * 1.1二叉搜索树的概念 * 1.2二叉搜索树的性能分析 * 二、二叉搜索树的实现 * 2.1二叉搜索树的整体框架 * 2.2二叉搜索树的插入 * 2.3二叉搜索树的查找 * 2.4二叉树的删除 * 三、二叉搜索树key和value的使用场景 * 四、总结 一、二叉搜索树的认识 1.1二叉搜索树的概念 二叉搜索树(

By Ne0inhk
【C++笔记】STL知识铺垫

【C++笔记】STL知识铺垫

前言:          在前面的学习中,我们已经掌握了C++的基础语法和编程概念,本文将深入探讨C++标准库的使用,并详细介绍迭代器、auto关键字以及范围for循环等相关知识。          一、STL简介          1.1 什么是STL          STL(Standard Template Library,标准模板库)是C++标准库的核心组成部分,它不仅提供了可复用的组件库,更是一个集成了高效数据结构与算法的软件框架。          1.2 STL的六大组件          由于历史原因,string 类型先于 STL 出现,STL 后来由惠普实验室开发并开源,因此人们通常不将 string 归入 STL 范畴。                   二、迭代器                  迭代器(Iterator)是 C++ STL 中最精妙的设计之一,如果把 STL 的容器比作各种不同类型的仓库(数组、链表、

By Ne0inhk
计算机基础知识总结(八股文总结----计算机网络、操作系统、数据库、c++、数据结构与算法)

计算机基础知识总结(八股文总结----计算机网络、操作系统、数据库、c++、数据结构与算法)

一、操作系统 0.内存管理 01.什么是虚拟内存?为什么需要虚拟内存? 虚拟内存为程序提供比实际物理内存更大的内存空间,同时提高内存管理的灵活性和系统的多任务处理能力。虚拟地址空间就是进程所能看到的内存空间,这段空间是连续的、独立的,实际地址空间则是内存上的空间,这段是所有进程共享的、有限的空间。虚拟内存就是把实际地址空间映射到虚拟地址空间的技术,这样就实现了内存隔离、内存扩展、物理内存管理、页面交换等技术。内存隔离就是每个进程都有自己的虚拟地址空间,因此一个进程无法访问另一个进程的内存。内存扩展就是虚拟内存让每个进程拥有比实际大的内存空间地址,可以处理更多的数据、更大的进程。物理内存管理,内存空间不足时把不常用的数据转移到硬盘上,释放内存,以助于更多进程使用。页面交换,进程可能会造成外部内存碎片,可能会导致内存空间不足,这时把不常用的数据交换到硬盘上,再交换回来,就能消除内存碎片,之前技术是内存分段,现在都是内存分页,一页或几页的内存交换就能解决内存不足的问题,而且效率高,内存分段的大数据在硬盘上读取速度慢。 02.什么是内存分段和分页?作用是什么? 内存分段是将一个程序

By Ne0inhk
C++:继承

C++:继承

Hello大家好! 很高兴与大家见面! 给生活添点快乐,开始今天的编程之路。 我的博客:<但愿. 我的专栏:C语言、题目精讲、算法与数据结构、C++ 欢迎点赞,关注 目录   一 继承的概念及定义        1.1继承的概念        1.2继承的定义               1.2.1定义格式               1.2.2类继承基类方式改变对应成员访问⽅式的变化               1.2.3  继承类模板【类继承类似】      二 基类和派⽣类间的转换          2.1不同的转换方式                 2.1.1会产生临时变量                 2.1.2不会产生临时变量(基类和派⽣类间的转换)                         2.1.2.1不会产生临时变量(

By Ne0inhk