当前位置: 首页 > news >正文

C语言连接【MySQL】

稍等更新图片。。。。

文章目录

  • 安装 MySQL 库
  • 连接 MySQL
    • MYSQL 类
    • 创建 MySQL 对象
    • 连接数据库
    • 关闭数据库连接
    • 示例
  • 发送命令
  • 设置编码格式
  • 插入、删除或修改记录
  • 查询记录
    • 示例
  • 参考资料

安装 MySQL 库

在 CentOS7 下,使用命令安装 MySQL:

yum install mysql-devel

/usr/include可以看到一个mysql新目录,里面存放的是 mysql 的头文件。另外在 /lib64/mysql/ 以及 /usr/lib64/mysql 目录下存放了 mysql 的动态和静态库。

用一个 MySQL 库提供的接口验证 MySQL 库是否安装成功:

#include <iostream>
#include <mysql/mysql.h>using namespace std;int main()
{cout << "mysql version: " << mysql_get_client_info() << endl;return 0;
}

编译:

g++ sql.cc -o sql -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
image-20240227182356233

编译选项中关于库的使用:

  • -I:用于指明头文件的搜索路径。
  • -L:用于指明库文件的搜索路径。
  • -l:用于指明需要连接库文件路径下的哪一个库。
image-20240227182921177

因为这个库没有在链接的默认目录/usr/lib64下,所以作为第三方导入的库,在编译时需要显式地指定-L/usr/lib64/mysql;同理,头文件不在默认目录/usr/include下,所以要显式地指定-I/usr/include/mysql。在这个目录下,存在名为mysqlclient的第三方库,同样需要用-l显式地声明。

只要正常运行上面的程序,那就表明库的链接没有问题,剩下的就是简单的 API 使用。

连接 MySQL

MYSQL 类

在使用 MySQL 提供的接口之前,需要了解一下这个重要的类。

MYSQL类是一个非常核心的结构体,它用于表示与 MySQL 服务器的一个连接实例。在客户端程序中,这个结构体用来保存客户端与数据库服务器之间连接的所有必要信息,包括但不限于:

  • 服务器的地址
  • 用户名和密码
  • 正在使用的数据库
  • 网络连接的状态和配置
  • 错误信息和错误码
  • 查询结果
  • 选项设置

mysql.h中可以查看 MYSQL 结构体的定义(了解即可):

typedef struct st_mysql
{NET		net;			/* Communication parameters */unsigned char	*connector_fd;		/* ConnectorFd for SSL */char		*host,*user,*passwd,*unix_socket,*server_version,*host_info;char          *info, *db;struct charset_info_st *charset;MYSQL_FIELD	*fields;MEM_ROOT	field_alloc;my_ulonglong affected_rows;my_ulonglong insert_id;		/* id if insert on table with NEXTNR */my_ulonglong extra_info;		/* Not used */unsigned long thread_id;		/* Id for connection in server */unsigned long packet_length;unsigned int	port;unsigned long client_flag,server_capabilities;unsigned int	protocol_version;unsigned int	field_count;unsigned int 	server_status;unsigned int  server_language;unsigned int	warning_count;struct st_mysql_options options;enum mysql_status status;my_bool	free_me;		/* If free in mysql_close */my_bool	reconnect;		/* set to 1 if automatic reconnect *//* session-wide random string */char	        scramble[SCRAMBLE_LENGTH+1];my_bool unused1;void *unused2, *unused3, *unused4, *unused5;LIST  *stmts;                     /* list of all statements */const struct st_mysql_methods *methods;void *thd;/*Points to boolean flag in MYSQL_RES  or MYSQL_STMT. We set this flag from mysql_stmt_close if close had to cancel result set of this object.*/my_bool *unbuffered_fetch_owner;/* needed for embedded server - no net buffer to store the 'info' */char *info_buffer;void *extension;
} MYSQL;
  • MYSQL 对象中的 methods 成员是一个结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。

创建 MySQL 对象

MYSQL* mysql_init(MYSQL *mysql);
  • 该函数用来分配或者初始化一个 MySQL 对象,用于连接 MySQL 服务器。
  • 如果传入的参数是 NULL,那么 mysql_init 将自动为你分配一个 MySQL 对象并返回。
  • 如果传入的参数是一个地址,那么 mysql_init 将在该地址处帮你完成初始化。

连接数据库

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

其中:

  • mysql: 表示在连接数据库前,调用 mysql_init 函数创建的 MySQL 对象。
  • host: 表示需要连接的 MySQL 服务器的 IP 地址,"127.0.0.1"表示连接本地 MySQL 服务器。
  • user: 表示连接 MySQL 服务器时,所使用用户的用户名。
  • passwd: 表示连接 MySQL 服务器时,所使用用户的密码
  • db: 表示连接 MySQL 服务器后,需要使用的数据库。
  • port: 表示连接的 MySQL 服务器,所对应的端口号。
  • unix_socket: 表示连接时应该使用的套接字或命名管道,通常设置为 NULL。
  • clientflag: 可以设置为多个标志位的组合,表示允许特定的功能,通常设置为 0。

返回值说明:

  • 如果连接数据库成功,则返回一个 MySQL 对象,该对象与第一个参数的值相同。
  • 如果连接数据库失败,则返回 NULL。

关闭数据库连接

void mysql_close(MYSQL *sock);

其中:

  • 该函数的参数,就是连接数据库前调用 mysql_init 创建的 MySQL 对象。
  • 如果传入的 MySQL 对象是 mysql_init 自动创建的,那么调用 mysql_close 时就会释放这个对象。

示例

在 MySQL 中首先有一个新用户:

grant all on curd_db.* to 'new_user'@'%' identified by '12345';

用户名是new_user%表示任意主机的用户,grant all表示它被授予所有权限在curd.db数据库下,密码是12345

在本地测试:

#include <iostream>
#include <string>
#include <mysql/mysql.h>
using namespace std;const string host = "localhost";
const string user = "new_user";
const string passwd = "12345";
const string db = "curd_db";
const int port = 3306;int main()
{// 1、创建 MySQL 对象MYSQL *mySQL = mysql_init(nullptr);// 2、连接数据库if (mysql_real_connect(mySQL, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr){cerr << "数据库连接失败!" << endl;exit(1);}cout << "数据库连接成功!" << endl;// 3、关闭数据库mysql_close(mySQL);cout << "数据库关闭成功!" << endl;return 0;
}

编译并运行:

image-20240227190559910

发送命令

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

数用于向 MySQL 服务器发送一个查询或命令,执行指定的 SQL 语句。

参数说明:

  • MYSQL *mysql:指向 MYSQL 结构体的指针,这个结构体代表了与 MySQL 服务器的一个连接。
  • const char *stmt_str:要执行的 SQL 语句的字符串。

返回值:

  • 成功执行时,返回 0
  • 出现错误时,返回非 0 值。

设置编码格式

在连接数据库之后,需要统一客户端和服务器的编码格式,避免在数据交互过程中出现乱码,设置编码格式的函数如下:

int mysql_set_character_set(MYSQL *mysql, const char *csname);

参数说明:

  • mysql: 表示在连接数据库前,调用 mysql_init 函数创建的 MySQL 对象。
  • csname: 表示要设置的编码格式,如"utf8"

返回值说明:

  • 返回值为 0 表示设置成功,否则表示设置失败。

插入、删除或修改记录

在 mysql_query 函数中向 MySQL 发送 INSERT SQL:

int main()
{// ...cout << "数据库连接成功!" << endl;// 设置编码mysql_set_character_set(mySQL, "utf8");// 插入记录string sql = "insert into account values(4,'小李',30,400)";if (mysql_query(mySQL, sql.c_str()) != 0){cout << "插入数据失败!" << endl;exit(2);}// ...return 0;
}

数据被成功插入到表中。

image-20240227193308014

类似地,可以删除和修改记录:

	string sql = "update account set balance=222 where id=2";
image-20240227193749866
	string sql = "delete from account where id=4";
image-20240227193844242

查询记录

对于 mysql_query 函数而言,插入、删除和修改操作都很简单,只要将 SQL 字符串作为参数传入即可,不需要返回值。但是 SELECT 查询需要返回结果,这需要使用到 MYSQL_RES 对象。

MYSQL_RES* mysql_store_result(MYSQL *mysql);
  • 该函数会调用指定 MySQL 对象中对应的函数指针来获取查询结果,并将获取到的查询结果保存到 MYSQL_RES 变量中进行返回。
  • 需要注意的是,MYSQL_RES 变量的内存空间是 malloc 出来的,因此在使用完后需要调用 free 函数进行释放,否则会造成内存泄露。

MYSQL_RES 变量中保存了查询得到的各种信息,其类型定义如下:

typedef struct st_mysql_res {my_ulonglong  row_count;MYSQL_FIELD	*fields;MYSQL_DATA	*data;MYSQL_ROWS	*data_cursor;unsigned long *lengths;		/* column lengths of current row */MYSQL		*handle;		/* for unbuffered reads */const struct st_mysql_methods *methods;MYSQL_ROW	row;			/* If unbuffered read */MYSQL_ROW	current_row;		/* buffer to current row */MEM_ROOT	field_alloc;unsigned int	field_count, current_field;my_bool	eof;			/* Used by mysql_fetch_row *//* mysql_stmt_close() had to cancel this result */my_bool       unbuffered_fetch_cancelled;void *extension;
} MYSQL_RES;

获取查询结果的行数:

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取查询结果的列数:

unsigned int mysql_num_fields(MYSQL_RES *res);

获取查询结果的列属性:

MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *res);

mysql_fetch_fields 函数将会返回多个 MYSQL_FIELD 对象,每个 MYSQL_FIELD 对象中保存着对应列的各种列属性,其类型定义如下:

typedef struct st_mysql_field {char *name;                 /* Name of column */char *org_name;             /* Original column name, if an alias */char *table;                /* Table of column if column was a field */char *org_table;            /* Org table name, if table was an alias */char *db;                   /* Database for table */char *catalog;	      /* Catalog for table */char *def;                  /* Default value (set by mysql_list_fields) */unsigned long length;       /* Width of column (create length) */unsigned long max_length;   /* Max width for selected set */unsigned int name_length;unsigned int org_name_length;unsigned int table_length;unsigned int org_table_length;unsigned int db_length;unsigned int catalog_length;unsigned int def_length;unsigned int flags;         /* Div flags */unsigned int decimals;      /* Number of decimals in field */unsigned int charsetnr;     /* Character set */enum enum_field_types type; /* Type of field. See mysql_com.h for types */void *extension;
} MYSQL_FIELD;

获取查询结果中的一行数据:

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

MYSQL_ROW 对象中保存着一行数据,这一行数据中可能包含多个字符串,对应就是这行数据中的多个列信息,因此 MYSQL_ROW 本质就是 char** 类型,其类型定义如下:

typedef char **MYSQL_ROW;		/* return data as array of strings */

示例

int main()
{// ...// 3、查询数据库表中的记录// a、执行查询语句string sql = "select * from account";if (mysql_query(mySQL, sql.c_str()) != 0){cout << "查询数据失败!" << endl;exit(2);}cout << "查询数据成功!" << endl;// b、获取查询结果MYSQL_RES *res = mysql_store_result(mySQL);int rows = mysql_num_rows(res);	  // 数据的行数int cols = mysql_num_fields(res); // 数据的列数// 获取每列的属性并打印列名MYSQL_FIELD *fields = mysql_fetch_fields(res);for (int i = 0; i < cols; i++){cout << fields[i].name << "\t";}cout << endl;for (int i = 0; i < rows; i++){// 获取一行数据并进行打印MYSQL_ROW row = mysql_fetch_row(res);for (int j = 0; j < cols; j++){cout << row[j] << "\t";}cout << endl;}// 释放内存空间free(res); // ...return 0;
}

参考资料

  • Linux centos 7/ubantu 下: 用 C 语言连接 MySQL 数据库
  • MySQL 使用 C 语言连接

相关文章:

C语言连接【MySQL】

稍等更新图片。。。。 文章目录 安装 MySQL 库连接 MySQLMYSQL 类创建 MySQL 对象连接数据库关闭数据库连接示例 发送命令设置编码格式插入、删除或修改记录查询记录示例 参考资料 安装 MySQL 库 在 CentOS7 下&#xff0c;使用命令安装 MySQL&#xff1a; yum install mysq…...

_note_09

1.说一说类加载的过程 加载&#xff08;Loading&#xff09; -> 验证&#xff08;Verification&#xff09; -> 准备&#xff08;Preparation&#xff09; -> 解析&#xff08;Resolution&#xff09; -> 初始化&#xff08;Initialization&#xff09;类的加载是…...

是否可以在HTTP中缓存POST方法

如果您想知道是否可以缓存post请求&#xff0c;并尝试研究该问题的答案&#xff0c;那么您很可能不会成功。当搜索“缓存post请求”时&#xff0c;第一个结果是这个StackOverflow问题。 答案是令人困惑的&#xff0c;包括缓存应该如何工作&#xff0c;缓存如何根据RFC工作&…...

Xilinx 7系列FPGA配置(ug470)

Xilinx 7系列FPGA配置&#xff08;ug470&#xff09; 配置模式串行配置模式接口从-连接方式主-连接方式串行菊花链&#xff08;非同时配置&#xff09;串行配置&#xff08;同时配置&#xff09;时序 主SPI配置模式SPIx1/x2 连接图SPIx1模式时序SPIx4 连接图SPI操作指令操作fla…...

3分钟开通GPT-4

AI从前年12月份到现在已经伴随我们一年多了&#xff0c;还有很多小伙伴不会开通&#xff0c;其实开通很简单&#xff0c;环境需要自己搞定&#xff0c;升级的话就需要一张visa卡&#xff0c;办理visa卡就可以直接升级chatgptPLSU 一、虚拟卡支付 这种方式的优点是操作简单&…...

Easticsearch性能优化之索引优化

Easticsearch性能优化之索引优化 一、合理的索引设计二、合理的分片和副本三、合理的索引设置 对于性能优化&#xff0c;Elasticsearch&#xff08;以下简称ES&#xff09;的索引优化是提高性能的关键因素之一。合理的设计索引&#xff0c;合理的分片和副本以及合理的缓存设置等…...

安装mysql-8.0.30-winx64(windows 64位)

1.下载 1.1下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2 .下载后解压缩目标文件 2.1之后在根目录下新建my.ini文件,并创建文件夹data &#xff08;新解压的文件没有my.ini文件&#xff0c;需自行创建 复制以下代码到my.ini文件 以下代码除安装目录和数据的…...

ios xcode 15 PrivacyInfo.xcprivacy 隐私清单

1.需要升级mac os系统到13 兼容 xcode 15.1 2.升级mac os系统到14 兼容 xcode 15.3 3.选择 New File 4.直接搜索 privacy 能看到有个App Privacy 5.右击Add Row 7.直接选 Label Types 8.选中继续添加就能添加你的隐私清单了 苹果官网文档Describing data use in privacy man…...

【物联网】-智能社会的分类

万物感知 感知物理世界&#xff0c;变成数字信号 &#xff08;温度、空间、触觉、嗅觉、听觉、视觉&#xff09; 万物互联 将数据变成online&#xff0c;使智能化 &#xff08;宽联接、广联接、多联接和深联接&#xff09; 万物智能 基于大数据和人工智能的应用 &#…...

Django高级之-cookie-session-token

Django高级之-cookie-session-token 发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新的HTTP协议&#xff0c; 就是请…...

【Prometheus】k8s集群部署node-exporter

​ 目录 一、概述 1.1 prometheus简介 1.2 prometheus架构图 1.3 Exporter介绍 1.4 监控指标 1.5 参数定义 1.6 默认启用的参数 1.7 prometheus如何收集k8s/服务的–三种方式收集 二、安装node-exporter组件 【Prometheus】概念和工作原理介绍-CSDN博客 【云原生】ku…...

2024年k8s最新版本安装教程

k8s安装教程 1 k8s介绍2 环境搭建2.1 主机准备2.2 主机初始化2.2.1 安装wget2.2.2 更换yum源2.2.3 常用软件安装2.2.4 关闭防火墙2.2.5 关闭selinux2.2.6 关闭 swap2.2.7 同步时间2.2.8 修改Linux内核参数2.2.9 配置ipvs功能 2.3 容器安装2.3.1 设置软件yum源2.3.2 安装docker软…...

Gin 获取请求参数

POST 请求参数 Gin 获取Post请求URL参数有三种方式 func (c *Context) PostForm(key string) string func (c *Context) DefaultPostForm(key, defaultValue string) string func (c *Context) GetPostForm(key string) (string, bool)大多数情况下使用的是application/x-www…...

安卓 Kotlin 面试题 31-40

&#x1f525; 31、简述Kotlin 中的内联类&#xff0c;我们什么时候需要&#xff1f;&#x1f525; 有时&#xff0c;业务逻辑需要围绕某种类型创建包装器。 但是&#xff0c;由于额外的堆分配&#xff0c;它会引入运行时开销。 此外&#xff0c;如果包装的类型是原始类型&…...

【洛谷千题详解】P1613 跑路

目录 题目总览 题目描述 输入格式 输出格式 思路分析 AC代码 题目总览 题目描述 小 A 的工作不仅繁琐&#xff0c;更有苛刻的规定&#xff0c;要求小 A 每天早上在 6:00 之前到达公司&#xff0c;否则这个月工资清零。可是小 A 偏偏又有赖床的坏毛病。于是为了保住自己的…...

如何定义resultType和resultMap,它们之间的区别是什么?解释一下<parameterType>的作用和用法。

在MyBatis中&#xff0c;resultType和resultMap都用于将数据库查询结果映射到Java对象&#xff0c;但它们在使用方式和灵活性上有一些区别。 resultType resultType是一个简单的类型别名&#xff0c;它用于指定查询结果应该映射到的Java类型。当数据库表中的列名和Java对象的属…...

Docker:部署微服务集群

1. 部署微服务集群 实现思路&#xff1a; ① 查看课前资料提供的cloud-demo文件夹&#xff0c;里面已经编写好了docker-compose文件 ② 修改自己的cloud-demo项目&#xff0c;将数据库、nacos地址都命名为docker-compose中的服务名 ③ 使用maven打包工具&#xff0c;将项目…...

傅里叶变换pytorch使用

参考视频&#xff1a;1 傅里叶变换原理_哔哩哔哩_bilibili 傅里叶变换是干嘛的&#xff1a; 傅里叶得到低频、高频信息&#xff0c;针对低频、高频处理能够实现不同的目的。 傅里叶过程是可逆的&#xff0c;图像经过傅里叶变换、逆傅里叶变换后&#xff0c;能够恢复到原始图像…...

LeetCode104 二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,…...

使用Spring的AOP

使用Spring的AOP 一、AOP 的常用注解1.切面类Aspect2.Pointcut3.前置通知Before4.后置通知AfterReturning5.环绕通知Around6.异常通知AfterThrowing7.最终通知After8.切面顺序Order9.启用自动代理EnableAspectJAutoProxy 二、AOP注解方式开发三、AOP 全注解开发四、基于XML配置…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...