ubuntu下如何使用C语言访问Mysql数据库(详细介绍并附有案例)

news2024/12/23 23:15:55

一、配置

        首先,确保你已经安装了MySQL服务器和MySQL Connector/C库。在Linux上,你可以使用包管理器来安装这些,例如:

sudo apt-get install mysql-server libmysqlclient-dev

在ubuntu的机器上,库文件通常保存在 /lib/x86_64-linux-gnu/ 目录下

zyq@iZ0jlcvs1yxxmicafyy3kbZ:~/linux/Connect_Mysql$ ls /lib/x86_64-linux-gnu/ | grep mysql
libmysqlclient.a
libmysqlclient.so
libmysqlclient.so.21
libmysqlclient.so.21.2.40
libmysqlservices.a

库的头文件通常保存在 /usr/include/mysql/ 目录下

zyq@iZ0jlcvs1yxxmicafyy3kbZ:~/linux/Connect_Mysql$ ls /usr/include/mysql/
client_plugin.h  my_compress.h   mysql.h          mysqlx_error.h
errmsg.h         my_list.h       mysql_time.h     mysqlx_version.h
field_types.h    mysql_com.h     mysql_version.h  plugin_auth_common.h
my_command.h     mysqld_error.h  mysqlx_ername.h  udf_registration_types.h

 在我们对访问mysql的程序编译时我们需要使用 -l 选项加上使用的库文件,注意动态库文件的名字是去掉前面的lib和后面的.so,例如:

connect:connect.cc 
	g++ -o $@ $^ -std=c++11 -lmysqlclient

而在Windows上,你需要从MySQL官方网站下载并安装MySQL服务器和MySQL Connector/C。

 二、C语言API介绍

2.1 mysql_init
MYSQL *mysql_init(MYSQL *mysql);

        这个函数的作用是进行初始化,要使用库,必须先进行初始化!如果函数执行成功他会返回一个MYSQL指针类型的操作数据库的句柄,失败则会返回null

        他的参数接受一个MYSQL结构体的指针作为参数。如果传入NULL,则函数会自动分配一个新的MYSQL结构

2.2 mysql_real_connect()
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结构体的指针、主机名、用户名、密码、数据库名、端口号、套接字路径和客户端标志等。

第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),MYSQL类型是一个结构体,它主要用于存储与MySQL服务器连接的相关信息,如主机名、用户名、密码、当前连接的数据库、连接状态等。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。

如果连接成功,返回MYSQL连接句柄(与第一个参数的值相同);如果连接失败,返回NULL。

注意:如果建立好链接之后,获取英文没有问题,获取中文是乱码的话我们需要手动设置一下编码格式, mysql_set_character_set(myfd, "utf8") 设置链接的默认字符集是utf8,原始默认是latin1

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

他的作用是向MySQL数据库发送一条sql语句,参数包括MYSQL连接句柄和要执行的SQL查询字符串。如果查询成功,对于SELECT、SHOW、EXPLAIN或DESCRIBE语句,返回一个资源标识符;对于其他类型的SQL语句,返回TRUE。如果查询失败,返回FALSE。

2.4 mysql_close
void mysql_close(MYSQL *sock);

该函数的功能是关闭与MySQL数据库的连接,并释放与MYSQL结构体关联的资源,参数是MYSQL连接句柄。


有了上面的四个基础接口,我们就可以执行一部分sql命令了,接下来我们举个例子:在一个表中插入一个数据

#include<mysql/mysql.h>
#include<iostream>
#include<string>
#include<unistd.h>
int main()
{
    MYSQL *mfp=mysql_init(nullptr);
    if(mfp==nullptr)
    {
        std::cerr<<"MYSQL INIT FALSE!"<<std::endl;
        return -1;
    }
    MYSQL *conn=mysql_real_connect(mfp,"8.130.115.39","connect","Zyq20040814.","test_connect",3306,nullptr,0);
    if(conn==nullptr)
    {
        std::cerr<<"MYSQL CONNECT FALSE!"<<std::endl;
        return -1;
    }
    mysql_set_character_set(mfp,"utf8");
    std::string op="insert into people values(3)";
    //std::string op="delete from people where id=3";
    if(mysql_query(mfp,op.c_str())==0)
    {
        std::cout<<op.c_str()<<" success!"<<std::endl;
    }
    else
    {
        std::cerr<<op.c_str()<<" false!"<<std::endl;
    }

    mysql_close(mfp);
    return 0;
}

问题: 

对于增删改的操作来说我们只需要关心他是否执行成功就行,他们也是最简单的,但是我们想一下,mysql_query的返回值是一个整形,但是如果我们执行的SQL语句是SELECT类型的查找语句呢,那查询到的结果保存在哪里呢,如何让上层获取这些数据呢?我们继续学习

2.5 mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql);

       当执行查询时,MySQL服务器会处理查询并生成结果集,该函数可以从服务器检索查询的全部结果集,并将其存储在客户端。如果成功返回一个MYSQL_RES结果集对象,如果失败则返回NULL。

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

2.6 mysql_num_rows

获取结果行数

my_ulonglong mysql_num_rows(MYSQL_RES *res);
2.7 mysql_num_fields

获取结果列数

unsigned int mysql_num_fields(MYSQL_RES *res);
2.7 mysql_fetch_fields

获取列名

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

MYSQL_FIELD是 MySQL C API 中用于描述查询结果集中列的信息的结构体。这个结构体包含了关于列的各种信息,如列名、数据类型、最大长度、是否允许为 NULL 等。

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;
2.8 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;
}

案例:

将查询到的数据打印出来:

#include <mysql/mysql.h>
#include <iostream>
#include <string>
#include <unistd.h>
int main()
{
    MYSQL *mfp = mysql_init(nullptr);
    if (mfp == nullptr)
    {
        std::cerr << "MYSQL INIT FALSE!" << std::endl;
        return -1;
    }
    MYSQL *conn = mysql_real_connect(mfp, "8.130.115.39", "connect", "Zyq20040814.", "test_connect", 3306, nullptr, 0);
    if (conn == nullptr)
    {
        std::cerr << "MYSQL CONNECT FALSE!" << std::endl;
        return -1;
    }
    mysql_set_character_set(mfp, "utf8");
    std::string op = "select * from people";
    if (mysql_query(mfp, op.c_str()) == 0)
    {
        std::cout << op.c_str() << " success!" << std::endl;
    }
    else
    {
        std::cerr << op.c_str() << " false!" << std::endl;
    }
    MYSQL_RES *res = mysql_store_result(mfp);
    int row = mysql_num_rows(res);
    int col = mysql_num_fields(res);
    //获取列名
    MYSQL_FIELD *field = mysql_fetch_fields(res);
    for (int i = 0; i < col; i++)
    {
        std::cout<<field->name<<"\t";
    }
    std::cout<<std::endl;
    //获取内容
    for(int i=0;i<row;i++)
    {
        MYSQL_ROW line=mysql_fetch_row(res);;
        for(int j=0;j<col;j++)
        {
            std::cout<<line[j]<<"\t";
        }
        std::cout<<std::endl;
    }
    mysql_free_result(res);
    mysql_close(mfp);
    return 0;
}

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

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

相关文章

uniapp接入BMapGL百度地图

下面代码兼容安卓APP和H5 百度地图官网&#xff1a;控制台 | 百度地图开放平台 应用类别选择《浏览器端》 /utils/map.js 需要设置你自己的key export function myBMapGL1() {return new Promise(function(resolve, reject) {if (typeof window.initMyBMapGL1 function) {r…

直播服务器多设备同显方案

在直播行业中&#xff0c;服务器多设备同显方案已成为一种创新且高效的技术应用。这一技术不仅能够满足大规模同步直播的需求&#xff0c;还能显著提升观众的观看体验和参与度。本文将深入探讨直播服务器多设备同显方案的技术细节、实施步骤以及在不同场景下的应用价值。 直播服…

101.【C语言】数据结构之二叉树的堆实现 下

目录 1.堆删除函数HeapPop 一个常见的错误想法:挪动删除 正确方法 设计堆顶删除函数HeapPop 解析向下调整函数AdjustDown 向下调整最多次数 向下调整的前提 代码实现 2.测试堆删除函数 运行结果 3.引申问题 运行结果 4.练习 分析 代码 执行过程图 运行结果 承…

数据结构(Java版)第二期:包装类和泛型

目录 一、包装类 1.1. 基本类型和对应的包装类 1.2. 装箱和拆箱 1.3. 自动装箱和自动拆箱 二、泛型的概念 三、引出泛型 3.1. 语法规则 3.2. 泛型的优点 四、类型擦除 4.1. 擦除的机制 五、泛型的上界 5.1. 泛型的上界的定义 5.2. 语法规则 六、泛型方法 6.1…

【pyspark学习从入门到精通14】MLlib_1

目录 包的概览 加载和转换数据 在前文中&#xff0c;我们学习了如何为建模准备数据。在本文中&#xff0c;我们将实际使用这些知识&#xff0c;使用 PySpark 的 MLlib 包构建一个分类模型。 MLlib 代表机器学习库。尽管 MLlib 现在处于维护模式&#xff0c;即它不再积极开发…

【CSP CCF记录】201903-1第16次认证 小中大

题目 样例1输入 3 -1 2 4 样例1输出 4 2 -1 样例1解释 4 为最大值&#xff0c;2 为中位数&#xff0c;−1 为最小值。 样例2输入 4 -2 -1 3 4 样例2输出 4 1 -2 样例2解释 4 为最大值&#xff0c;(−13)21为中位数&#xff0c;−2为最小值。 思路 本题两个注意点&#xff0…

P8692 [蓝桥杯 2019 国 C] 数正方形:结论,组合数学

题目描述 在一个 NNNN 的点阵上&#xff0c;取其中 44 个点恰好组成一个正方形的 44 个顶点&#xff0c;一共有多少种不同的取法&#xff1f; 由于结果可能非常大&#xff0c;你只需要输出模 10971097 的余数。 如上图所示的正方形都是合法的。 输入格式 输入包含一个整数 …

Elasticsearch客户端在和集群连接时,如何选择特定的节点执行请求的?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f; 100…

【题解】—— LeetCode一周小结46

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结45 11.切棍子的最小成本 题目链接&#xff1a;1547. 切棍子的最…

AI社媒引流工具:解锁智能化营销的新未来

在数字化浪潮的推动下&#xff0c;社交媒体成为品牌营销的主战场。然而&#xff0c;面对海量的用户数据和日益复杂的运营需求&#xff0c;传统营销方法显得力不从心。AI社媒引流王应运而生&#xff0c;帮助企业在多平台中精准触达目标用户&#xff0c;提升营销效率和效果。 1.…

Python 使用 Selenuim进行自动化点击入门,谷歌驱动,以百度为例

一、首先要下载谷歌驱动 1.&#xff08;打开谷歌浏览器 - 设置 - 关于谷歌&#xff0c;查看谷歌浏览器版本&#xff0c;否则不对应无法调用&#xff0c;会提示&#xff1a;selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This versio…

C语言-指针作为函数返回值及二级指针

1、指针作为函数返回值 c语言允许函数的返回值是一个指针&#xff08;地址&#xff09;我们将这样的函数称为指针函数&#xff0c;下面的例子定义一了一个函数strlong&#xff08;&#xff09;&#xff0c;用来返回两个字符串中较长的一个&#xff1a; 1. #include <stdio…

实时数据开发 | 怎么通俗理解Flink容错机制,提到的checkpoint、barrier、Savepoint、sink都是什么

今天学Flink的关键技术–容错机制&#xff0c;用一些通俗的比喻来讲这个复杂的过程。参考自《离线和实时大数据开发实战》 需要先回顾昨天发的Flink关键概念 检查点&#xff08;checkpoint&#xff09; Flink容错机制的核心是分布式数据流和状态的快照&#xff0c;从而当分布…

再次讨论下孤注一掷

在孤注一掷中的黑客技术里面&#xff0c;简单介绍了电影孤注一掷中用的一些"黑科技"&#xff0c;这里继续讨论下&#xff0c;抛弃这些黑科技&#xff0c;即使在绝对公平的情况下&#xff0c;你也一样赢不了赌场 相对论有一个假设就是光速不变&#xff0c;这里也有个…

微信小程序技术架构图

一、视图层1.WXML&#xff08;WeiXin Markup Language&#xff09; 这是微信小程序的标记语言&#xff0c;类似于 HTML。它用于构建小程序的页面结构。例如&#xff0c;通过标签来定义各种视图元素&#xff0c;如<view>&#xff08;类似于 HTML 中的<div>&#xff…

GaussDB 华为高斯数据库

GaussDB 是华为推出的一款企业级分布式数据库&#xff0c;旨在为企业提供高效、可靠、安全的数据库服务。GaussDB 基于华为在数据库领域的多年积累&#xff0c;结合人工智能技术和分布式架构&#xff0c;支持多种场景的数据存储与管理需求&#xff0c;是云计算、大数据、人工智…

redis工程实战介绍(含面试题)

文章目录 redis单线程VS多线程面试题**redis是多线程还是单线程,为什么是单线程****聊聊redis的多线程特性和IO多路复用****io多路复用模型****redis如此快的原因** BigKey大批量插入数据测试数据key面试题海量数据里查询某一固定前缀的key如果生产上限值keys * &#xff0c;fl…

C++从零到满绩——入门基础and类和对象(上)

目录 1>>前言 2>>函数重载 3>>引用 3.1>>引用的概念 3.2>>引用三大特性 3.3>>引用的使用 3.4>>const引用 3.5>>指针与引用的关系 4>>inline内联函数 5>>nullptr 6>>类和对象&#xff08;上&#…

DDPM与DDIM中的采样

在深度生成模型中&#xff0c;采样&#xff08;Sampling&#xff09;指的是根据模型生成新样本的过程。在扩散模型&#xff08;Diffusion Models&#xff09;中&#xff0c;采样的关键是从高斯噪声逐步还原出原始数据。让我们分别探讨 DDPM 和 DDIM 的采样过程&#xff0c;以及…

python oa服务器巡检报告脚本的重构和修改(适应数盾OTP)有空再去改

Two-Step Vertification required&#xff1a; Please enter the mobile app OTPverification code: 01.因为巡检的服务器要双因子认证登录&#xff0c;也就是登录堡垒机时还要输入验证码。这对我的巡检查服务器的工作带来了不便。它的机制是每一次登录&#xff0c;算一次会话…