MySQL-MySQL访问

news2024/11/18 11:33:50

文章目录

  • 前言
  • 一、使用步骤
    • 1.MYSQL *mysql_init(MYSQL *mysql);
    • 2.MYSQL *mysql_real_connect
    • int mysql_query(MYSQL *mysql, const char *q);
    • MYSQL_RES *mysql_store_result(MYSQL *mysql);
      • 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_ROW mysql_fetch_row(MYSQL_RES *result);
    • 所有源代码


前言

通过之前的章节,我们已经学会了MySQL的大部分基本操作和概念,今天我们将要学习通过C语言接口来访问MySQL。

需要注意的是,今天我们要使用的接口都来自于第三方库,这个库是由MySQL提供的,我们需要用到 mysql.h 和 mysqlclient.so ,头文件一般在/usr/include/mysql/,动态库文件有的在/usr/lib/或者/usr/lib64/中,不过我的就在/usr/lib/x86_64-linux-gnu/目录下,所以如果你找不到的话,可以直接使用sudo find / -name libmysqlclient.so来直接查找。

当然前提是你的主机安装了mysql,一般会自动给你添加这些库文件。

g++ -o test test.cc -std=c++11 -lmysqlclient -L /usr/lib/x86_64-linux-gnu/

一、使用步骤

1.MYSQL *mysql_init(MYSQL *mysql);

就像是我们之前的要使用Windos下的网络通信一样,需要先初始化环境,这个接口函数就是初始化当前的环境。

MYSQL *mysql_ptr = mysql_init(nullptr);

后续我们要进行对mysql进行连接就需要用上该返回值MYSQL*

2.MYSQL *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_init的返回值,
参数const char *user,
const char *passwd,
const char *db,
unsigned int port 很显而易见。

至于最后两个参数我们这里暂时不作考虑。

如果连接失败,则会返回nullptr。


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

const std::string host = "127.0.0.1";
const std::string user = "fengjunzi";
const std::string passwd = "wdnmdsb1";
const std::string database = "test_db";
const unsigned int port = 3306;
int main()
{

    MYSQL *mysql_ptr = mysql_init(nullptr);
    if (mysql_ptr == nullptr)
    {
        std::cerr << "MySQL Init Error" << std::endl;
        mysql_close(mysql_ptr);
        exit(1);
    }
    if (mysql_real_connect(mysql_ptr, host.c_str(), user.c_str(), passwd.c_str(), database.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "MySQL Connect Error" << std::endl;
        mysql_close(mysql_ptr);
        exit(2);
    }

    std::cout << "MySQL Connect Success" << std::endl;
}

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

这个函数就是用来对连接的mysql下达指令的函数,参数const char *q就是你下达的指令的字符串。

    //模拟mysql输入命令行
	while (true)
    {
        std::cout << "mysql> ";
        if (!std::getline(std::cin, mysql_statement) || mysql_statement == "quit" || mysql_statement == "quit;")
        {
            std::cout << "bye bye" << std::endl;
            break;
        }
        int n = mysql_query(mysql_ptr, mysql_statement.c_str());
        if (n == 0)
        {
            std::cout << "MySQL Query Success" << std::endl;
        }
        else
        {
            std::cerr << "MySQL Query Error" << std::endl;
            break;
        }

通过mysql_query我们确实可以给mysql下达指令,但是,我们如果调用select,其实是没有反应的,那么如果我们要读取内容显示出来,应该怎么办呢?

如何做到获取select结果?
在这里插入图片描述

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 中的数据。

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取结果行数mysql_num_rows

unsigned int mysql_num_fields(MYSQL_RES *res);

获取结果列数mysql_num_fields

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

获取列名mysql_fetch_fields

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

用于获取行内容数据,返回的MYSQL_ROW其实是一个char**。

        if (mysql_statement.substr(0,6) == "select")
        {
            MYSQL_RES *result = mysql_store_result(mysql_ptr);
            MYSQL_FIELD *field_array = mysql_fetch_fields(result); // 获取列名
            unsigned int fields = mysql_num_fields(result);        // 获取列数
            unsigned int rows = mysql_num_rows(result);            // 获取行数

            for (int i = 0; i < fields; i++)
            {
                std::cout << field_array[i].name << "\t";
            }
            std::cout << std::endl;

            for (int i = 0; i < rows; i++)
            {
                MYSQL_ROW line = mysql_fetch_row(result); // typedef MYSQL_ROW char**
                for (int j = 0; j < fields; j++)
                {
                    std::cout << line[j] << "\t";
                }
                std::cout << std::endl;
            }
            free(result);  //记得free,不然会造成内存泄漏!
        }

在这里插入图片描述

所有源代码

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

const std::string host = "127.0.0.1";
const std::string user = "fengjunzi";
const std::string passwd = "wdnmdsb1";
const std::string database = "test_db";
const unsigned int port = 3306;
int main()
{
    // std::cout << "mysql version: " << mysql_get_client_info() << std::endl;

    MYSQL *mysql_ptr = mysql_init(nullptr);
    if (mysql_ptr == nullptr)
    {
        std::cerr << "MySQL Init Error" << std::endl;
        mysql_close(mysql_ptr);
        exit(1);
    }
    if (mysql_real_connect(mysql_ptr, host.c_str(), user.c_str(), passwd.c_str(), database.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "MySQL Connect Error" << std::endl;
        mysql_close(mysql_ptr);
        exit(2);
    }

    std::cout << "MySQL Connect Success" << std::endl;

    mysql_set_character_set(mysql_ptr, "utf8"); //将我向目标mysql发送的字符编码变为utf8

    // std::string mysql_statement = "insert into user (name, age) values('李四',13)";
    //  std::string mysql_statement = "select * from user";
    std::string mysql_statement;
    while (true)
    {
        std::cout << "mysql> ";
        // mysql_statement = "";
        if (!std::getline(std::cin, mysql_statement) || mysql_statement == "quit" || mysql_statement == "quit;")
        {
            std::cout << "bye bye" << std::endl;
            break;
        }
        int n = mysql_query(mysql_ptr, mysql_statement.c_str());
        if (n == 0)
        {
            std::cout << "MySQL Query Success" << std::endl;
        }
        else
        {
            std::cerr << "MySQL Query Error" << std::endl;
            break;
        }



        if (mysql_statement.substr(0,6) == "select")
        {
            MYSQL_RES *result = mysql_store_result(mysql_ptr);
            MYSQL_FIELD *field_array = mysql_fetch_fields(result); // 获取列名
            unsigned int fields = mysql_num_fields(result);        // 获取列数
            unsigned int rows = mysql_num_rows(result);            // 获取行数

            for (int i = 0; i < fields; i++)
            {
                std::cout << field_array[i].name << "\t";
            }
            std::cout << std::endl;

            for (int i = 0; i < rows; i++)
            {
                MYSQL_ROW line = mysql_fetch_row(result); // typedef MYSQL_ROW char**
                for (int j = 0; j < fields; j++)
                {
                    std::cout << line[j] << "\t";
                }
                std::cout << std::endl;
            }
            free(result);  //记得free,不然会造成内存泄漏!
        }
    }

    mysql_close(mysql_ptr);
    return 0;
}

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

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

相关文章

秋招内推2025--招联金融

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递&#xff09; 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…

CRC循环校验的功能

CRC (Cyclic Redundancy Check&#xff0c;循环冗余校验) 是一种常用的错误检测码&#xff0c;用于检测数据传输或存储过程中发生的错误。它通过在数据末尾添加一个校验码&#xff08;CRC码&#xff09;来实现。接收方通过同样的算法计算接收数据的CRC码&#xff0c;并将结果与…

DC00022基于ssm高校社团管理系统web社团管理系统java web+MySQL项目web程序设计

1、项目功能演示 DC00022基于ssm高校社团管理系统web社团管理系统java web项目MySQL 2、项目功能描述 社团管理系统分为普通用户、管理员 2.1 普通用户功能 01 系统登录、系统注册 02 系统首页、新闻公告、规章制度、社团活动、互动交流 03 修改密码 04 个人信息修改 05 我的…

Tair简介

概述 Tair是淘宝团队开源的高可用分布式KV存储引擎&#xff0c;采用服务端自动负载均衡方式&#xff0c;使客户端逻辑简单。Tair&#xff0c;即TaoBao Pair缩写&#xff0c;Pair表示一对、一双等意思&#xff0c;即Key-Value数据对。 Tair分为持久化和非持久化两种方式。非持…

C++ 发布包问题汇总

C 发布包问题汇总 1、64位系统 拷贝 C:\Windows\SysWOW64 文件夹下面的DLL 2、32位系统 拷贝C:\Windows\System32文件夹下面的DLL 3、 程序所需dll问题 使用vs调试&#xff0c;在调试界面会打印出加载的dll 4、拷贝dll问题 64位拷贝了32位的dll就会出现加载失败的问题&a…

Java语言之数据类型与变量

Java的数据类型主要分为两类 基本数据类型&#xff1a;整形&#xff08;包括&#xff1a;字节型&#xff1a;byte、1个字节,短整型&#xff1a;short、两个字节&#xff0c;整形&#xff1a;int、4个字节&#xff0c;长整型&#xff1a;long、8个字节&#xff09;&#xff0c;…

swagger v2默认访问地址

SpringBoot项目启动默认访问地址&#xff1a;swagger-ui.html 2024-09-27 08:40:59.744 INFO 248900 --- [ main] o.a.coyote.http11.Http11NioProtocol : Starting ProtocolHandler ["http-nio-9090"] 2024-09-27 08:40:59.756 INFO 248900 --- […

三数之和为0

1. 问题描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元…

Vscode超好看的渐变主题插件

样式效果&#xff1a; 插件使用方法&#xff1a; 然后重启&#xff0c;之后会显示vccode损坏&#xff0c;不用理会&#xff0c;因为这个插件是更改了应用内部代码&#xff0c;直接不再显示即可。

GUPAO-AI大模型实战训练营-大模型原理及训练技巧、大模型微调的核心原理

在当今科技日新月异的时代&#xff0c;大模型已经成为人工智能领域的重要支柱。GUPAO-AI大模型实战训练营&#xff0c;正是为了深入解析这些庞然大物背后的原理&#xff0c;以及如何有效利用它们进行实际操作和微调。本文将带你走进大模型的殿堂&#xff0c;揭示其原理&#xf…

【重学 MySQL】四十二、单行子查询

【重学 MySQL】四十二、单行子查询 单行子查询的基本用法示例1&#xff1a;查找薪资高于公司平均水平的员工示例2&#xff1a;查找没有分配项目的员工示例3&#xff1a;使用单行子查询进行等值比较 注意事项 在MySQL中&#xff0c;子查询&#xff08;Subquery&#xff09;是一种…

VUE 整合 ECharts

一、vue 引入 ECharts依赖 npm install echarts --save 二、创建盒子 <div ref"chars" style"height: 500px;width:800px;"></div> 解释说明 ref"chars" 是 Vue.js 中一个非常有用的特性&#xff0c;用于给 DOM 元素或组件实例…

CrossOver24支持的游戏有那些

CrossOver刚刚更新了24版本&#xff0c;支持《地平线零之曙光》、《以撒的结合&#xff1a;重生》等游戏。一起来看看它有哪些更新吧&#xff01; 一、功能优化 - 更新 Wine 至最新的稳定版 Wine 9.0&#xff0c;引入了 7000多个更新和针对各种软件游戏的优化。 - 更新 Wine M…

Android平台GB28181实时回传流程和技术实现

规范解读 GB28181 中的 “INVITE” 是会话初始协议&#xff08;SIP&#xff09;中的一种请求方法&#xff0c;主要用于邀请一个或多个参与者加入特定的会话。在 GB28181 标准中&#xff0c;“INVITE” 请求通常用于发起媒体流的传输请求。当一个设备想要接收来自另一个设备的媒…

Linux上安装Jenkins并展示allure报告

1. 确认安装正确的java版本 到官网War Jenkins Packages查看Jenkins版本匹配的java版本&#xff0c;我这里选择安装java11 使用java --version命令是否已安装java版本 java --version 如上图所示&#xff0c;暂未安装java版本&#xff0c;我这里选择安装java11&#xff08;je…

基于SpringBoot+Vue+MySQL的在线酷听音乐系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展&#xff0c;网络已成为人们日常生活中不可或缺的一部分。在线音乐服务因其便捷性和丰富性&#xff0c;逐渐成为用户获取音乐内容的主要渠道。然而&#xff0c;传统的音乐播放平台往往存在歌曲资源有限…

进程组、会话、守护进程和线程的概念

1.进程组和会话 1.1 概念和特性 进程组&#xff0c;也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念&#xff0c;是为了简化对多个进…

微信小程序-数据模型与动态赋值

首先新建一个小程序项目. 这边有创建基础项目的流程:从0新建一个微信小程序实现一个简单跳转_小白开发小程序源代码-CSDN博客 一共两步: 1.建立页面的 数据模型 和 默认赋值: 默认赋值: 2.接收输入框的新文案,动态替换上面的文案展示 //文件 testUI.js增加方法:onInputChan…

当 ucx --with-cuda 时做了什么

1&#xff0c;找一只活麻雀&#xff0c;下载编译 ucx git clone https://github.com/openucx/ucx.git cd ucx/ git checkout v1.16.0 ./autogen.sh ./autogen.sh mkdir build cd build ../contrib/configure-devel --with-cuda/usr/local/cuda --without-rocm --without-java …

JavaScript 知识点 - 作用域(变量提升、垃圾回收机制、闭包)

一、作用域 1、基本概念 是什么? 指变量、对象和函数在【代码中的可访问性范围】。 有什么用? 理解作用域对【编写高效和无错误的代码】至关重要 分类 局部作用域&#xff08;函数作用域、块作用域&#xff09;、全局作用域 涉及到那些知识点 作用域链、JS垃圾回收机…