C语言链接数据库

目录

使用 yum 配置 mysqld 环境

查看 mysqld 服务的版本

创建 mysql 句柄 

链接数据库 

使用数据库 

增加数据 

修改数据

 查询数据

 获取查询结果的行数

 获取查询结果的列数 

获取查询结果的列名 

获取查询结果所有数据

断开链接 

C语言访问mysql数据库整体源码


        通过前段时间的 mysql 数据库的学习,我们知道了 mysql 数据库本质上就是一个网络服务,本期的主要内容在于讲解如何使用 C 语言相关的接口连接 mysqld 网络服务。

使用 yum 配置 mysqld 环境

        centos7 版本的操作系统使用一下指令安装 mysqld 服务的配置文件。

sudo yum install mysql-devel

        配置好之后,mysqld 相关的头文件在 /usr/include/mysql 目录下。我们连接 mysqld 服务时主要使用 mysql.h 头文件。

        配置好后。mysqld 对应的库文件在 /usr/lib64/mysql 下。

        在链接 mysqlclient 库时,需要使用 -L 字段指明库的路径。 

g++ -o $@ $^ -std=c++11  -L/usr/lib64/mysql -lmysqlclient

查看 mysqld 服务的版本

  • 使用 mysql_get_client_info() 函数查看 mysqld 云服务版本。 
  std::cout<<"client version: "<<mysql_get_client_info()<<std::endl;

        作者的版本是 mysql 5.7.44 版本。

创建 mysql 句柄 

  • 使用 mysql_init() 函数创建 mysql 句柄。
  MYSQL *my=mysql_init(nullptr);

链接数据库 

  • 使用 mysql_real_connect() 函数链接数据库。
#include<iostream>
#include<cstdio>
#include<mysql/mysql.h>const std::string host="127.0.0.1";
const std::string user="jd";
const std::string password="YJD010918madeinchina...";
const std::string db="study";
const unsigned int port=8088;int main()
{std::cout<<"client version: "<<mysql_get_client_info()<<std::endl;//1.创建mysql句柄MYSQL *my=mysql_init(nullptr);//2.链接数据库if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0)==nullptr){std::cout<<"connect failed!"<<std::endl;return 1;}std::cout<<"connect success!"<<std::endl;
}

        第一个参数为刚开始创建的 mysql 句柄,第二个参数为要访问的 mysqld 的 ip,第三个参数为使用哪个 mysql 用户访问数据库, 第四个参数为访问数据库的这个 mysql 用户的密码是多少,第四个参数为当前用户访问的数据库的名称,第五个参数为访问的 mysqld 的端口号,后面两个参数不需要了解。返回值为 MYSQL* 数据库句柄类型,如果为空则连接数据库失败,如果不为空则链接数据库成功。

使用数据库 

        数据库的使用其实就是对数据库表的使用,数据库表的使用包含四个部分数据记录的 增加,查询,修改,删除

        无论是 增加,查询,修改还是删除,都使用下面的函数进行操作。

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

        在对数据进行操作之前,我们应该先设置 mysql 句柄的编码格式。

 //设置句柄的编码格式mysql_set_character_set(my,"utf8");

增加数据 

        向 study 数据库中的 students 表中插入数据。

insert into students values (6,66,'张三','297599');

        成功插入。 

修改数据

        向 study 数据库中的 students 表中修改数据。 

update from students set name='李四' where id =6;

        成功修改。 

 查询数据

        查询数据是数据操作中较为复杂的一个操作,因为涉及到了将数据查询出来,并将数据显示出来。查询出来数据很简单,但是复杂的是将查询出来的数据显示出来,如何显示出来,我们需要使用 多个接口共同搭配使用将插叙出来的数据显示出来。

        查询 students 表中的所有记录。

select * from students;

        使用下述函数读取  mysql_query()  接口执行之后,mysql 句柄中查询的结果。

MYSQL_RES *mysql_store_result(MYSQL *mysql);
     MYSQL_RES* res=mysql_store_result(my);

        读取的结果存储在了 MYSQL_RES* 类型的返回值指向的特定结构体中。后续使用这个返回值获取相关的结果字段。

 获取查询结果的行数

        使用以下函数查询行数。

 my_ulonglong mysql_num_rows(MYSQL_RES *res);
    //4.2获取查询的行数unsigned int rows = mysql_num_rows(res);std::cout << rows << std::endl;

        查询列数成功。 

 获取查询结果的列数 

        使用以下函数查询列数。

 unsigned int mysql_num_fields(MYSQL_RES *res);
    unsigned int fields = mysql_num_fields(res);std::cout << fields << std::endl;

        查询列数成功。

获取查询结果的列名 

        使用以下函数查询列名。

 MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res); 
//4.3获取查询记录的每一列的列名称MYSQL_FIELD* fields_name=mysql_fetch_field(res);for(int i=0;i<fields;i++){std::cout<<fields_name[i].name<<"\t";}std::cout<<std::endl;

        查询结果的列名称获取成功。

获取查询结果所有数据

        1.先使用以下函数获取查询结果的所有行数据。

 MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); 

        可以将 MYSQL_ROW 看做一个二维数组。

for(int i=0;i<rows;i++){MYSQL_ROW lines=mysql_fetch_row(res);//line[i]表示第几行的数据,直接获取是无法获取的,因为无法知道这一行数据的列数//就相当于如果只知道二维数组的行标不知道列表也是无法访问二维数组的元素的}

        2.通过列数,然后再访问每行的每个元素,最终实现所有查询结果的访问。但是要注意,每列的元素都不应为空,否则会出现一些异常打印的问题。

        基于此,对 students 中为空的字段进行修改。

 std::cout << std::endl;for (int i = 0; i < rows; i++){MYSQL_ROW lines = mysql_fetch_row(res);// line[i]表示第几行的数据,直接获取是无法获取的,因为无法知道这一行数据的列数// 就相当于如果只知道二维数组的行标不知道列表也是无法访问二维数组的元素的for (int j = 0; j < fields; j++){std::cout << lines[j] << "\t";}std::cout << std::endl;}

        查询结果的所有数据获取成功。 

断开链接 

        使用以下函数断开链接。

 void mysql_close(MYSQL *sock);
    free(res);mysql_close(my);

C语言访问mysql数据库整体源码

#include <iostream>
#include <stdlib.h>
#include <string>
#include <mysql/mysql.h>const std::string host = "127.0.0.1";
const std::string user = "jd";
const std::string password = "YJD010918madeinchina...";
const std::string db = "study";
const unsigned int port = 8088;int main()
{std::cout << "client version: " << mysql_get_client_info() << std::endl;// 1.创建mysql句柄MYSQL *my = mysql_init(nullptr);// 2.链接数据库if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr){std::cout << "connect failed!" << std::endl;return 1;}// 3.设置链接的编码格式mysql_set_character_set(my, "utf8");std::cout << "connect success!" << std::endl;// 4.进行数据库表操作std::string sql = "select * from students";int code = mysql_query(my, sql.c_str());if (code != 0){std::cout << "execute: " << sql << "failed!" << std::endl;return 2;}std::cout << "execute: " << sql << " success!" << std::endl;// 4.1获取查询的结果到res中MYSQL_RES *res = mysql_store_result(my);// 4.2获取查询的行数int rows = mysql_num_rows(res);std::cout << rows << std::endl;int fields = mysql_num_fields(res);std::cout << fields << std::endl;// 4.3获取查询记录的每一列的列名称MYSQL_FIELD *fields_name = mysql_fetch_field(res);for (int i = 0; i < fields; i++){std::cout << fields_name[i].name << "\t";}// 4.4获取查询结果的每一行的数据std::cout << std::endl;for (int i = 0; i < rows; i++){MYSQL_ROW lines = mysql_fetch_row(res);// line[i]表示第几行的数据,直接获取是无法获取的,因为无法知道这一行数据的列数// 就相当于如果只知道二维数组的行标不知道列表也是无法访问二维数组的元素的for (int j = 0; j < fields; j++){std::cout << lines[j] << "\t";}std::cout << std::endl;}//5.断开链接mysql_close(my);
}

        至此,C语言链接数据库的操作全部完成。

        本期内容到此结束^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Maven】手动安装依赖到本地仓库

【Maven】手动安装依赖到本地仓库 【一】下载依赖【二】安装 JAR 文件到本地仓库【三】验证安装【四】在项目中使用该依赖【1】注意事项【2】额外提示 【一】下载依赖 登录到中央仓库下载依赖&#xff0c;中央仓库地址&#xff1a;https://mvnrepository.com/ 搜搜你的依赖的a…

腾讯云golang一面

go垃圾回收机制 参考自&#xff1a;https://zhuanlan.zhihu.com/p/334999060 go 1.3 标记清除法 缺点 go 1.5 三色标记法 屏障机制 插入屏障 但是如果栈不添加,当全部三色标记扫描之后,栈上有可能依然存在白色对象被引用的情况(如上图的对象9). 所以要对栈重新进行三色标记扫…

跨平台嵌入式音视频开发指南:EasyRTC音视频通话的多场景适配与AI扩展能力

在数字化通信技术飞速发展的今天&#xff0c;实时音视频通信已成为众多智能设备和应用的核心功能。从智能家居到远程办公&#xff0c;从在线教育到智能安防&#xff0c;音视频通信技术的应用场景不断拓展&#xff0c;对低延迟、高稳定性和跨平台兼容性的需求也在持续增长。在这…

Android 11 去掉性能受到影响通知

源码位置: frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java final void finishBooting() {TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",Trace.TRACE_TAG_ACTIVITY_MANAGER);t.traceBegin("Finis…

Mac idea WordExcel等文件git modify 一直提示修改状态

CRLF LF CR 换行符自动转换问题 查看状态&#xff1a;git config --global --list Mac需要开启&#xff0c;window下需要关闭 关闭命令&#xff1a;git config --global core.autocrlf false 命令解释&#xff1a; autocrlf true 表示要求git在提交时将crlf转换为lf&a…

Apache Commons CLI 入门教程:轻松解析命令行参数

文章目录 Apache Commons CLI 入门教程&#xff1a;轻松解析命令行参数一、什么是 Commons CLI&#xff1f;二、为什么选择 Commons CLI&#xff1f;三、快速开始1. 添加依赖2. 基础示例3. 运行示例1. 在Idea中运行2. 命令行中运行3. 使用 Maven/Gradle 运行&#xff08;推荐&a…

VS2022调试嵌入式linux C# 程序 高效的开发方案

1.目标板子配置好ssh,确保PC可以连上 2.目标板子上传VSDBG程序&#xff0c;详见我的上一个文章 3.PC安装winfsp&#xff0c; sshfs,SSHFS-Win Manager.傻瓜式安装&#xff0c;将目标板子映射到PC的某个盘 4.VS2022中&#xff0c;你的工程的exe生成目录到上面盘中某个路径 5…

Python中如何加密/解密敏感信息(如用户密码、token)

敏感信息,如用户密码、API密钥、访问令牌(token)、信用卡号以及其他个人身份信息(PII),构成了现代应用程序和系统中最为关键的部分。这些信息一旦被未经授权的第三方获取,可能引发灾难性的后果,从个人隐私泄露到企业经济损失,甚至是大规模的社会安全问题。保护这些敏感…

智能体开发的范式革命:Cangjie Magic全景解读与实践思考

引言&#xff1a;当智能体开发遇见仓颉魔法 在人工智能技术日新月异的今天&#xff0c;智能体(Agent)开发正从实验室走向产业应用的核心舞台。2025年3月&#xff0c;仓颉社区推出的Cangjie Magic开源平台&#xff0c;以其创新的设计理念和技术架构&#xff0c;为这一领域带来了…

【Java学习笔记】位运算

位运算 一、原码&#xff0c;反码&#xff0c;补码 (1) 二进制的最高位是符号位&#xff1a;0 表示正数&#xff0c;1 表示负数&#xff08;怎么记&#xff1f; 1旋转一下变成-&#xff09; (2) 正数的原码、反码、补码都一样&#xff08;三码合一&#xff09; (3) 负数的反码…

HttpSessionBindingListener 的用法笔记250417

HttpSessionBindingListener 的用法笔记250417 HttpSessionBindingListener 是 Java Servlet 规范中 唯一 由 被存储对象自身实现 的会话监听接口&#xff0c; 1. 核心功能 HttpSessionBindingListener 是一个由 会话属性对象自身实现 的接口&#xff0c;用于监听该对象被绑定…

【HDFS入门】HDFS高可用性与容错机制深度解析

目录 引言 1 HDFS高可用架构实现 1.1 基于QJM的NameNode HA架构 1.2 QJM vs NFS实现对比 2 故障切换流程与ZooKeeper作用 2.1 自动故障转移流程 2.2 状态转换机制 3 数据恢复与副本管理 3.1 DataNode故障处理流程 4 快照与数据保护机制 4.1 HDFS快照架构 4.2 快照使…

04-libVLC的视频播放器:获取媒体信息

libvlc_media_t* libvlc_media_player_get_media(libvlc_media_player_t* p_mi); 功能说明 核心作用:获取与媒体播放器关联的当前媒体对象返回值:成功:返回libvlc_media_t*指针失败/无关联媒体:返回NULL内存管理:返回的媒体对象引用计数会增加,需要使用libvlc_media_rele…

使用datax通过HbaseShell封装writer和reader同步hbase数据到hbase_踩坑_细节总结---大数据之DataX工作笔记008

最近在做大数据相关功能,有个需求,使用datax同步hbase到hbase中,其中还是有很多细节值得记录: 首先来看一下datax的源码中,如果你使用phoenix创建的表,那么 你就需要使用对应的hbase带有sql字样的,reader和writer. 然后如果你使用datax-web来进行测试的,那么,他默认使用的是h…

如何通过window端来ssh连接本地虚拟机的ubuntu

首先在 Ubuntu 虚拟机上安装和配置 SSH 服务&#xff1a; # 安装 SSH 服务器 sudo apt update sudo apt install openssh-server# 检查 SSH 服务状态 sudo systemctl status ssh# 如果没有启动&#xff0c;则启动 SSH 服务 sudo systemctl start ssh# 设置开机自启动 sudo sys…

Anolis OS 8.10 发布:软硬协同优化,满足多行业实际应用需求

引言 龙蜥操作系统 Anolis OS 8 是 OpenAnolis 龙蜥社区发行的开源 Linux 发行版&#xff0c;支持多计算架构&#xff0c;提供稳定、高性能、安全、可靠的操作系统支持。Anolis OS 8.10 是 Anolis OS 8 发布的第六个小版本&#xff0c;通过软硬协同&#xff0c;不断完善生态&a…

Java八种常见的设计模式

一、单例模式 单例模式是&#xff08;Singleton Pattern&#xff09;Java中最常用的设计模式之一&#xff0c;它保证一个类仅有一个实例&#xff0c;并提供一个全局访问点。 实现单例模式的核心是将类的构造方法私有化&#xff0c;以防止外部直接通过构造函数创建实例。同时&am…

4.17---实现商铺和缓存与数据库双写一致以及宕机处理

实现商铺和缓存与数据库双写一致&#xff08;以及强双写一致策略&#xff09; redis点评项目采用的是延时双删策略 双删&#xff1a; 我们更新完数据库之后删除缓存&#xff0c;这样即使有线程并发进来查询&#xff0c;会发现缓存中没有数据&#xff0c;从而会去mysql中查找…

滑动窗口209. 长度最小的子数组

1.题目 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&…

osu ai 论文笔记 DQN

e https://theses.liacs.nl/pdf/2019-2020-SteeJvander.pdf Creating an AI for the Rhytm Game osu! 20年的论文 用监督学习训练移动模型100首歌能达到95准确率 点击模型用DQN两千首歌65准确率 V抖用的居然不是强化学习&#xff1f; 5,6星打96准确度还是有的东西的 这是5.…