MySQL 使用C语言

一般使用MySQL很少用命令行,一般都是通过程序内部使用,MySQL也为不同的语言定制了不同的头文件和库函数,可以在自己的程序中通过包含头文件和编译时候链接库函数来使用MySQL。

现在一般安装MySQL的时候就会自动给你安装库函数和头文件。

可以自行通过以下命令查看。

查看库函数                          ls /usr/lib64/mysql

 查看头文件                        ls /usr/include/mysql

 如果没有的话,可以通过以下命令来安装。

安装开发库                         yum install -y mysql-community-devel

然后使用mysql的话,就通过包含头文件以及链接库函数来使用。

包含头文件                      #include<mysql.h> / #include<mysql/mysql.h> 

包含的头文件都是 mysql.h ,但是左边这种方式由于没有指定目录,因此在编译的时候需要添加指定路径

编译链接             

没指定路径:g++ -o test test.cc -I/include/mysql -L/lib64/mysql -lmysqlclient

指定路径:   g++ -o test test.cc  -L/lib64/mysql -lmysqlclient

-I : 这里的 I 是 i 的大写,表明指定头文件的目录

-L : 表明库文件的路径

-l : 这里的 l 是 L 的小写,表明链接的库文件

如果指定了头文件的路径,编译的时候就只需要链接库了。 

MySQL接口介绍

mysql_init()

想要使用一个数据库,必须先初始化。

 通过该函数可以创建一个MYSQL句柄,用来后续操作,传递的值可以为空。

mysql_real_connect()

该函数是通过 init 函数创建的句柄,来和特定的数据库进行连接。

失败返回NULL,成功则返回传入的句柄。

需要指定host,用户,密码,数据库,端口号,最后两个参数可以采用默认,直接填 nullptr 和 0 即可。

 mysql_query()

该函数可以用以下达对应的命令,如 select,insert 之类的语句。

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

下面做一个实验,来一一试试上面的函数和语句。

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

using namespace std;

const string host = "localhost";
const string user = "lbx";
const string password = "124533lbxLBX..";
const string db = "rootDB";
const unsigned int port = 3306;

int main()
{
    MYSQL * my;
    my = mysql_init(nullptr);
    if(my != NULL) cout<<"mysql init successed"<<endl;
    else cout<<"muysql init failed!"<<endl;

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0))
    cout<<"mysql connect successed !"<<endl;
    else cout<<"mysql connect failed !"<<endl;


    // string sql = "insert into test (name,age) values ('tom',12)";
    // string sqp = "delete from test where id = 2";
    // string sql = "update test set name='jack' where id=1";
    string sql = "select * from test";
    if(mysql_query(my,sql.c_str())) cout<<"mysql insert failed!"<<endl;
    else cout<<"mysql insert successed!"<<endl;

    mysql_close(my);
    return 0;
}

发现实验结果确实如预想的那样。

但是有个问题!select语句在这里没有现象,需要配合其他函数使用。

注意:有些版本的mysql在远程连接使用的时候,插入数据有中文字符的时候,可能会出现乱码,我这里的版本是 8.0的,因此没有问题,不过如果插入的数据有乱码时,可以通过

int mysql_set_character_set(MYSQL* mysql,  const char* csname)来设置字符集为utf8

 mysql_store_result

针对select语句需要输出或者查看内容的情况,mysql提供该函数来将select 的数据从mysql句柄中提取到 MYSQL_RES 中,然后再输出。

MYSQL_RES 是一个MySQL的一种结构体,能够保存存储在 MYSQL 类型变量中的数据。

不过这个函数的返回值是一个指针,因此肯定在程序中开辟了一块空间,这块空间需要手动释放。

MySQL提供函数用于释放该指针

mysql_free_result()

该函数是专门用来释放MYSQL_RES指针的空间的。 

 如何查看MYSQL_RES中的数据

实际上MYSQL_RES和MYSQL类型一样,都是一个句柄。

因此是无法直接从MYSQL_RES中直接读取数据的,因此MySQL还提供了其他几个函数配合提取数据。

mysql_num_rows()

该函数能够从 MYSQL_RES 中提取数据的行数。 

mysql_num_fields() 

该函数能够从 MYSQL_RES 中提取数据的列数。 

mysql_fetch_fields() 

该函数能够一次性获取所有列名,其返回值类似于一个数组指针,想访问其内容可以采用访问数组指针内容的方式。 

 

 不过 MYSQL_FIELD 本身是一个类,想获取列名还需要知道该类有什么样的成员。

我们可以直接查看该类的成员结构。

 其中列名分为列名和原列名,表明也是。这是因为select查询语句可以对列名进行重命名,因此会出现两个类似的变量。

mysql_fetch_row()

该函数能够获取结果内容,即每一行的内容。

而返回值的 MYSQL_ROW 类型实际上就是一个 char** 类型,因为接受的数据都是以字符串的形式接受的,因此想读取一行的数据,也是当作是一个二维数组来直接操作。

 实验

我们写下如下的代码来实验是否能够得到 select 的数据。

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

using namespace std;

const string host = "localhost";
const string user = "lbx";
const string password = "124533lbxLBX..";
const string db = "rootDB";
const unsigned int port = 3306;

int main()
{
    MYSQL * my;
    my = mysql_init(nullptr);
    if(my != NULL) cout<<"mysql init successed"<<endl;
    else cout<<"muysql init failed!"<<endl;

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0))
    cout<<"mysql connect successed !"<<endl;
    else cout<<"mysql connect failed !"<<endl;


    // string sql = "insert into test (name,age) values ('张三',12)";
    // string sqp = "delete from test where id = 2";
    // string sql = "update test set name='jack' where id=1";
    string sql = "select * from test";
    if(mysql_query(my,sql.c_str())) cout<<"mysql select failed!"<<endl;
    else cout<<"mysql select successed!"<<endl;

    //将数据从my中提取到res中
    MYSQL_RES* res = mysql_store_result(my);
    //获取数据的行数
    my_ulonglong row = mysql_num_rows(res);
    //获取数据的列数
    unsigned int col = mysql_num_fields(res);
    //获取数据的名称
    MYSQL_FIELD* file_name = mysql_fetch_fields(res);
    
    //输出列名
    for(int i = 0; i < col; i++)
    {
        cout<<file_name[i].name<<"\t";
    }
    cout<<endl;
    MYSQL_ROW line;
    for(int i = 0; i < row; i++)
    {
        //获取一行的数据
        line = mysql_fetch_row(res);
        // cout<<line[0]<<"\t"<<line[1]<<"\t"<<line[2]<<"\t";
        for(int j = 0; j < col; j++)
        {
            cout<<line[j]<<"\t";
        }
        cout<<endl;
    }
    mysql_close(my);
    return 0;
}

发现确实成功获得了数据。

此外。,有一个细节。

 

在这里,我们每次都是直接通过 mysql_fetch_row 来获取一行数据,没有说我们要获得哪一行的数据,但是结果却是正确的结果。

这是因为 res 就类似一个缓冲区,每通过 mysql_fetch_row 获取一行数据时,都会将提取出去的一行数据给删除,因此可以直接获取。

其他的函数

我们当然可以通过C语言链接来做类似于事务的操作。

首先我们可以通过 mysql_query() 来执行启动事务。

 

mysql_autocommit()

该函数用于启动事务。

这个函数可以开始事务是否自动提交。

我们可以通过 mode 参数来设置是否开启自动提交。

1 表示启动自动提交,0表示关闭自动提交。

mysql_commit()

 当启动一个事务可以通过该函数直接提交。

0 表示提交成功,其他表示失败

mysql_rollback()

该函数能够回滚事务。

 

0表示回滚成功, 其他表示失败。 

总结 

本文总结了C/C++如何连接mysql,然后也介绍了连接的函数以及一些注意事项,也介绍了select时的特殊情况所用的函数,并进行了实践,希望对各位有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

洛谷P1229 遍历问题

洛谷P1229 遍历问题 遍历问题 文章目录 遍历问题题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 正确代码 题目描述 我们都很熟悉二叉树的前序、中序、后序遍历&#xff0c;在数据结构中常提出这样的问题&#xff1a;已知一棵二叉树的前序和中序遍历&#xff0c;求它…

SpringBoot 启动分析

一、序言 本文简单分析一下 SpringBoot 的启动流程。 二、SpringBoot 启动源码分析 public ConfigurableApplicationContext run(String... args) {// 记录当前时间的纳秒数&#xff0c;用于计算应用程序启动所花费的时间long startTime System.nanoTime();// 创建一个默认…

构建第一个ArkTS用的资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

【神经网络与深度学习】Long short-term memory网络(LSTM)

简单介绍 API介绍&#xff1a; nn.LSTM(input_size100, hidden_size10, num_layers1,batch_firstTrue, bidirectionalTrue)inuput_size: embedding_dim hidden_size: 每一层LSTM单元的数量 num_layers: RNN中LSTM的层数 batch_first: True对应[batch_size, seq_len, embedding…

fpga基础|如何在XDC文件中使用get_pins/ports/cells/nets/clocks查找指定的对象

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

P1706 全排列问题

原题链接:全排列问题 - 洛谷 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 dfs典题 3. 代码实现 #define _CRT_SECURE_NO_WARNINGS 1 #include<bits/stdc.h> using namespace std; #define ll long long #define endl \n const int N 2…

SaaS知识库工具推荐来了,有这些就够用了!

在快节奏、以信息为核心的工作环境中&#xff0c;如何有效管理和共享知识成为了很多企业面临的一大挑战。幸运的是&#xff0c;现在市面上有许多出色的SaaS&#xff08;Software as a Service&#xff09;知识库工具可以帮助我们。这些工具便捷、高效&#xff0c;能够满足各种规…

pycharm爬虫模块(scrapy)基础使用

今天学了个爬虫。在此记录 目录 一.通过scrapy在命令行创建爬虫项目 二.判断数据为静态还是动态 三.pycharm中的设置 三:爬虫主体 四.pipelines配置&#xff08;保存数据的&#xff09; 五.最终结果 一.通过scrapy在命令行创建爬虫项目 1.首先需要在cmd中进入到python文…

2024.4.15

代码&#xff1a;uart4.c #include "uart4.h"void uart4_config() {//使能GPIO\GPIOG\UART4的外设时钟RCC->MP_AHB4ENSETR | (0x1<<1);RCC->MP_AHB4ENSETR | (0x1<<6);RCC->MP_APB1ENSETR | (0x1<<16);//设置PB2和PG11为管脚复用功能//P…

游戏行业科普 (二)游戏是怎么做出来,怎么卖出去的?

游戏行业科普系列文章&#xff0c;大家可以关注起来&#xff0c;等我慢慢分享~~ 《蛋仔派对》 一、研运流程--游戏是怎么做出来的 一款游戏的开发和运营大体上可以分为预研立项、设计开发、测试调优、发行上线和成熟运营几个阶段。 1&#xff09;预研立项&#xff1a; 初始研…

YOLOv9有效改进专栏汇总|未来更新卷积、主干、检测头注意力机制、特征融合方式等创新![2024/4/14]

​ 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 专栏介绍 YOLOv9作为最新的YOLO系列模型&#xff0c;对于做目标检测的同学是必不可少的。本专栏将针对2024年最新推出的YOLOv9检测模型&#xff0…

Matlab|基于广义Benders分解法的综合能源系统优化规划

目录 1 主要内容 广义benders分解法流程图&#xff1a; 优化目标&#xff1a; 约束条件&#xff1a; 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现文章《综合能源系统协同运行策略与规划研究》第四章内容基于广义Benders分解法的综合能源系统优化规划&…

树莓派点亮双色LED

双色LED灯准确来说叫双基色LED灯,是指模块只能显示2种颜色,一般是红色和绿色,可以有三种状态 :灭,颜色1亮,颜色2亮,根据颜色组合的不同,分为红蓝双色,黄蓝双色,红绿双色等等。 接线:将引脚S(绿色)和中间引脚(红色)连接到Raspberry Pi的GPIO接口上,对Raspberry…

针对MaxCompute优化案例分享

声明 原文来源&#xff1a;微信公众号&#xff1a;阿里云开发者 前言 MaxCompute 是阿里巴巴集团推出的一种大数据计算平台&#xff0c;用于处理海量数据和进行数据分析。它提供了高可靠性、高扩展性和高性能的数据处理能力&#xff0c;支持 SQL 查询、MapReduce 计算和机器…

1113. 红与黑--Flood Fill 算法

目录 1113. 红与黑--Flood Fill 算法---宽搜&#xff08;BFS&#xff09;或DFS&#xff09; 输入格式 输出格式 数据范围 输入样例&#xff1a; 输出样例&#xff1a; 思路&#xff1a; 1.BFS 思路&#xff1a; 2.DFS 思路 方法一&#xff1a;&#xff08;BFS&#x…

hadoop最新详细版安装教程 2024 最新版

文章目录 hadoop安装教程 2024最新版提前准备工作用户配置安装 SSH Server免密登录设置编辑 SSH server 配置文件配置Java环境查看java 版本验证 环境变量设置安装Hadoop下载hadoop解压hadoop查看hadoop 版本hadoop 配置编辑编辑配置文件core-site.xml编辑配置文件hdfs-site.xm…

使用深度学习集成模型进行乳腺癌组织病理学图像分类

基于预训练的VGG16和VGG19架构训练了四种不同的模型&#xff08;即完全训练的 VGG16、微调的 VGG16、完全训练的 VGG19 和微调的 VGG19 模型&#xff09;。最初&#xff0c;我们对所有单独的模型进行了5倍交叉验证操作。然后&#xff0c;我们采用集成策略&#xff0c;取预测概率…

深度学习框架

深度学习框架 1 引言 在当今技术加速发展的时代&#xff0c;深度学习已经成为了人工智能领域内最为引人注目的子领域之一。其在图像识别、自然语言处理、自动驾驶等多个行业中的成功应用&#xff0c;已经证明了深度学习在解决复杂问题方面的巨大潜力。然而&#xff0c;深度学习…

package.java文件的作用

你查看springboot的源码&#xff0c;有很多类都有这个文件&#xff0c;在idea不能创建&#xff0c;因为不支持这种命名&#xff0c;只能用记事本创建后复制都项目中。 主要应用是给类添加正常&#xff0c;或者把公用的注解都放到这里&#xff0c;常量不合适&#xff0c;作用范…

动态消息系统设计

动态消息流是一个在你个人主页不同更定的故事列表&#xff0c;推特、mega和Instagram 的post消息都是典型的动态消息列表&#xff0c;和普通消息流系统的最大区别是消息流动态变化、实时更新&#xff0c;设计一个动态消息系统核心功能消息流的构建和消息的发布&#xff0c;需要…