MySQL——通过C语言连接

news2024/11/25 6:44:39

文章目录

    • 1、前置安装
    • 2、正式连接
      • 增加
      • 删除
      • 修改
      • select

1、前置安装

前提:

如果你的mysql是通过yum安装的,那么那些库文件依赖,都是有的,不用你安装了。

但是如果是用 rpm包安装的,就需要去官网下载对应的包。

这些是连接使用的动静态库:

在这里插入图片描述

这些是连接使用的头文件:

在这里插入图片描述

### makefile

test_mysql:mysql_test.cc
	g++ -o $@ $^ -std=c++11

.PHONY:clean
	rm -rf test_mysql


### mysql_test.cc

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

// using namespace std;

int main()
{
    std::cout << "client version" << mysql_get_client_info() << std::endl;
    return 0;
}

在这里插入图片描述

编译的时候会有报错信息,原因:我们用的函数mysql_get_client_info() 它是在mysqlclient.so 库中,我们使用g++编译器的时候,需要指定链接第三方库的库名字

在这里插入图片描述

修改Makefile之后,还是找不到???

排查错误:

在这里插入图片描述

发现并没有这个库,暂时不知道是什么原因,我们改用原生的方法!

官网网址:[https://downloads.mysql.com/archives/c-c/]

到官网去下载库文件,原生拷贝

在这里插入图片描述

然后上传到Linux中

使用:

tar -小镇微风(xzwf) 名字

在这里插入图片描述

mv 将解压后的目录改短一点

在这里插入图片描述

再次回到项目即可引用:

建立两个软连接

在这里插入图片描述

更新Makefile:

test_mysql:mysql_test.cc
	g++ -o $@ $^ -std=c++11 -lmysqlclient -I./include -L./lib

.PHONY:clean
	rm -rf test_mysql

在这里插入图片描述

终于引入成功了!!!

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

有点激动!花了一个小时!

在这里插入图片描述

2、正式连接

步骤:

1、连接数据库

2、访问数据库

3、关闭数据库

三步走战略

但是连接之前呢,我们需要有一个对象

0️⃣首先创建一个对象(MYSQL句柄)

MYSQL* mysql_init(MYSQL *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;

1️⃣连接数据库

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对象,该对象与第一个参数的值相同。
  • 如果连接数据库失败,则返回NULL。

2️⃣CURD

3️⃣关闭数据库

void mysql_close(MYSQL *sock);
#include <iostream>
#include <cstdio>
#include <string>
#include <mysql/mysql.h>

const std::string host = "127.0.0.1";
const std::string user = "sjj";
const std::string password = "20020606sjj";
const std::string db = "test_db";
const unsigned int port = 3306;

// using namespace std;

int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD

    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

在这里插入图片描述

CURD操作:

在这里插入图片描述

我们先预设一点数据在student表中

在这里插入图片描述


在这里插入图片描述


再次插入:

在这里插入图片描述

在这里插入图片描述

增加

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

const std::string host = "127.0.0.1";
const std::string user = "sjj";
const std::string password = "20020606sjj";
const std::string db = "test_db";
const unsigned int port = 3306;

// using namespace std;

int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    mysql_set_character_set(my, "utf8");
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD
    std::string sql = "insert into student values (9 ,99,\'王五\')";
    int res = mysql_query(my, sql.c_str());
    // std::cout << "res = " << res << std::endl;
    if (res != 0)
    {
        std::cout << "execute: " << sql << " faild" << std::endl;
        return 2;
    }
    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

在这里插入图片描述

删除

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

const std::string host = "127.0.0.1";
const std::string user = "sjj";
const std::string password = "20020606sjj";
const std::string db = "test_db";
const unsigned int port = 3306;

// using namespace std;

int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    mysql_set_character_set(my, "utf8");
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD
     //std::string sql = "insert into student values (9 ,99,\'王五\')";
    std::string sql = "delete from student where id=9";
    int res = mysql_query(my, sql.c_str());
    //std::cout << "res = " << res << std::endl;
    if (res != 0)
    {
        std::cout << "execute: " << sql << " faild!" << std::endl;
        return 2;
    }
    std::cout << "execute: " << sql << " success!" << std::endl;

    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

在这里插入图片描述

修改

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

const std::string host = "127.0.0.1";
const std::string user = "sjj";
const std::string password = "20020606sjj";
const std::string db = "test_db";
const unsigned int port = 3306;

// using namespace std;

int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    mysql_set_character_set(my, "utf8");
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD
    // std::string sql = "insert into student values (9 ,99,\'王五\')";
    // std::string sql = "delete from student where id=9";
    std::string sql = "update student set name=\'张益达\' where name=\'张三\' ";
    int res = mysql_query(my, sql.c_str());
    // std::cout << "res = " << res << std::endl;
    if (res != 0)
    {
        std::cout << "execute: " << sql << " faild!" << std::endl;
        return 2;
    }
    std::cout << "execute: " << sql << " success!" << std::endl;

    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

在这里插入图片描述

以上三个其实是最基础的操作

select其实是不好处理的,select sql执行完毕,只是第一步,还需要对于数据进行进一步处理解析!!

select

  • 下发mysql命令mysql_query
int mysql_query(MYSQL *mysql,const char* q)

第二个参数是要执行的sql语句,如“ select * from student”

  • 获取执行结果mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql)

如果是update、insert语句,那么我们只需要知道操作成功了吗就可以了,但是如果是select 语句,我们还需要读取数据,因为要将数据打印到屏幕上去。如何读取查询数据呢,如果mysql_query语句执行成功,那么我们就通过mysql_store_result来读取结果。

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;

通过下面的函数来读取MYSQL_RES中的数据:

1️⃣获取行数

my_ulonglong mysql_num_rows(MYSQL_RES *res)

2️⃣获取列数

unsigned int mysql_num_fields(MYSQL_RES *res)
int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    mysql_set_character_set(my, "utf8");
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD

    std::string sql = "select * from student";
    int code = mysql_query(my, sql.c_str());
    if (code != 0)
    {
        std::cout << "execute: " << sql << " faild!" << std::endl;
        return 2;
    }
    std::cout << "execute: " << sql << " success!" << std::endl;

    // 这里需要对于数据处理,因为要打印在屏幕上面方便人观看
    MYSQL_RES *result= mysql_store_result(my);
    int rows =mysql_num_rows(result);
    int cols =mysql_num_fields(result);
    std::cout<<"行数:"<< rows <<", 列数:"<<cols<<std::endl;

    free(result);
    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

在这里插入图片描述

3️⃣获取列名

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res)

在这里插入图片描述

4️⃣获取结果内容

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
    
它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char ** 
就当成一个二维数组来用吧。

在这里插入图片描述

完整代码:

int main()
{
    // std::cout << "client version " << mysql_get_client_info() << std::endl;
    //  0.首先要创建mysql句柄
    MYSQL *my = mysql_init(nullptr);

    // 1.连接数据库
    if (mysql_real_connect(my,
                           host.c_str(),
                           user.c_str(),
                           password.c_str(),
                           db.c_str(),
                           port,
                           nullptr, 0) == nullptr)

    {
        std::cout << "connect faild!" << std::endl;
        return 1;
    }
    mysql_set_character_set(my, "utf8");
    std::cout << "connect success!" << std::endl;

    // 2.中间操作 CURD

    std::string sql = "select * from student";
    int code = mysql_query(my, sql.c_str());
    if (code != 0)
    {
        std::cout << "execute: " << sql << " faild!" << std::endl;
        return 2;
    }
    std::cout << "execute: " << sql << " success!" << std::endl;

    // 这里需要对于数据处理,因为要打印在屏幕上面方便人观看
    MYSQL_RES *result = mysql_store_result(my);

    // 1--获取行数、列数
    int rows = mysql_num_rows(result);
    int cols = mysql_num_fields(result);
    std::cout << "行数:" << rows << ", 列数:" << cols << std::endl;

    // 2--获取表中列名
    MYSQL_FIELD *fields = mysql_fetch_fields(result);
    for (int i = 0; i < cols; i++)
    {
        std::cout << fields[i].name << "\t";
    }
    std::cout << std::endl;

    // 3--获取表中数据
    for (int i = 0; i < rows; i++)
    {
        MYSQL_ROW line = mysql_fetch_row(result);
        for (int j = 0; j < cols; j++)
        {
            std::cout << line[j] << "\t";
        }
        std::cout << std::endl;
    }
    free(result);
    // 3、 关闭数据库
    mysql_close(my);
    return 0;
}

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

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

相关文章

操作系统与进程调度

文章目录 一、计算机操作系统1.操作系统&#xff08;Operating System&#xff09;2.计算机系统示意图 二、进程1.进程/任务&#xff08;Process/Task&#xff09;2.进程控制块抽象(PCB Process Control Block)3.进程调度(Process Scheduling&#xff09;4.内存管理&#xff08…

知识点回顾(一)

1.final,finally ,finalize final?修饰符&#xff08;关键字&#xff09;如果一个类被声明为final&#xff0c;意味着它不能再派生出新的子类&#xff0c;不能作为父类被继承。因此一个类不能既被声明为 abstract的&#xff0c;又被声明为final的。将变量或方法声明为final&…

ChatGPT潜能无限:多个震撼应用场景一一揭晓

ChatGPT 具有对个人、公司和各个行业非常有用的各种应用程序。在本文中&#xff0c;我们继续解释ChatGPT 应用&#xff08;基础应用场景&#xff0c;请点击这里查看&#xff09;。 看完此篇文章中&#xff0c;你会非常惊讶于起潜能无限的应用场景及其强大的功能&#xff0c;那…

Nginx之rewrite实现URL重写

1.开篇 rewrite是nginx服务器提供的一个重要功能&#xff0c;用于实现URL的重写。例如我们访问https://aa.qq.com&#xff0c;打开的是https://age.qq.com/&#xff0c;这就是使用URL重写的特性来实现的。 ngx_http_rewrite_module为实现URL重写提供了指令支持。 官方文档地…

ChatGPT教程(终极版)

新建了一个网站 https://ai.weoknow.com/ 每天给大家更新可用的国内可用chatGPT 这是一篇姗姗来迟的ChatGPT教程。 小白对ChatGPT的介绍足以让你阅读我的文章。 如果你已经使用过ChatGPT&#xff0c;那么祝贺你发现了宝藏。未来的先进技术一定会帮助你有所收获。 前提是你可…

我的『1024』创作纪念日

记得&#xff0c;2020年07月22日我撰写了第1篇技术博客&#xff1a;《遗传算法实例解析》在这平凡的一天&#xff0c;我赋予了它不平凡的意义也许是立志成为一名专业T作者、也许是记录一段刚实践的经验但在那一刻&#xff0c;我已在创作这趟旅程中出发今天&#xff0c;是我成为…

百度蜘蛛简介

百度蜘蛛简介 工作机制百度蜘蛛的工作要素百度蜘蛛原理的应用Baiduspider对一个网站服务器造成的访问压力如何&#xff1f;Baiduspider多长时间之后会重新抓取我的网页&#xff1f; 工作机制 百度蜘蛛的构建的原理。搜索引擎构建一个调度程序&#xff0c;来调度百度蜘蛛的工作…

2023.5.13>>Eclipse+exe4j打包Java项目及获取exe所在文件的路径

Eclipseexe4j打包Java项目及获取exe所在文件的路径 1、打包exe文件1.1 打jar包1.2 打包exe2、在程序中获取exe所在路径3、遇到问题4、JDK version和class file version(Class编译版本号)对应关系5、参考文章 1、打包exe文件 1.1 打jar包 右单击项目选择“Export…” 1.2…

软考A计划-真题-分类精讲汇总-第三章(数据库)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

小程序开发中的插件、组件、控件到底有什么区别?

小程序插件代码由一些自定义组件和 JS 代码文件构成&#xff0c;插件开发者在发布插件时&#xff0c;这些代码被上传到后台保存起来。当小程序使用插件时&#xff0c;使用者需填写插件的 AppID 和版本号&#xff0c;就可从后台获取相应的插件代码。小程序代码编译时&#xff0c…

基于 CentOS 7 构建 LVS-DR 群集

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 前言&#xff1a; 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式其各自的优势 DR 模式 原理&#xff1a;首先…

Hadoop之block切片

切片是一个逻辑概念 在不改变现在数据存储的情况下&#xff0c;可以控制参与计算的节点数目 通过切片大小可以达到控制计算节点数量的目的 有多少个切片就会执行多少个Map任务 hdfs上数据存储的一个单元,同一个文件中块的大小都是相同的 因为数据存储到HDFS上不可变&#xff0…

Qt--QString字符串类、QTimer定时器类

目录 1. QString 字符串类 dialog.cpp 2. 容器类 2.1 顺序容器 QList 示例代码&#xff1a; student.h student.cpp dialog.h dialog.cpp 运行结果&#xff1a; 2.2 关联容器 QMap 示例代码&#xff1a; dialog.h dialog.cpp 运行结果&#xff1a; 3. Qt类型 3.1 跨平台数据类型…

中断相关内容大全

中断基本概念&#xff1a;程序中断指计算机执行现行程序过程中&#xff0c;出现某种急需处理的异常情况或特殊请求&#xff0c;CPU暂时中止现行程序&#xff0c;而转去对这些异常情况或特殊请求进行处理&#xff0c;处理完毕后CPU又自动返回到现行程序的断点处&#xff0c;继续…

【刷题之路】LeetCode24——详解两两交换链表中的结点的细节

一、题目描述 原题链接&#xff1a;https://leetcode.cn/problems/swap-nodes-in-pairs/comments/ 题目描述&#xff1a;给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&am…

linux下将结果保存为图片,因为服务器是命令行界面,无法弹出窗口

解决方法来自GitHub&#xff1a;https://github.com/open-mmlab/mmdetection/issues/1405 The code below can show and save image with result. import mmcv import cv2 from mmcv.runner import load_checkpoint from mmdet.models import build_detector from mmdet.apis i…

C语言结构体位域

目录 一、C语言位域是什么&#xff1f; 二、位域详解 定义格式&#xff1a; 1. 数据类型排序改变&#xff0c;位域长度不变 2. 数据类型排序不变&#xff0c;位域长度改变 3.根据以上代码的验证可以得出以下计算位域结构体数据的方法: 三.位域的结构体数据如何进行print…

感恩有你:毕业论文致谢部分写作指南

现在正值毕业论文写作最后收尾阶段&#xff0c;估计很多同学开始各处收集如何写致谢这个部分。之前写过一篇文章中引用一位导师的“抱怨”&#xff0c;文章题目为“211导师深夜含泪发文&#xff1a;在你长达5万字的毕业论文中&#xff0c;我最欣赏致谢部分”&#xff0c;所以为…

Java面试题spring

Spring 1、不同版本的 Spring Framework 有哪些主要功能&#xff1f; 2、什么是 Spring Framework&#xff1f; Spring 是一个开源应用框架&#xff0c;旨在降低应用程序开发的复杂度。它是轻量级、松散耦合的。 它具有分层体系结构&#xff0c;允许用户选择组件&#xff0c…

国考省考行测:资料分析题,年均增长量

国考省考行测&#xff1a;资料分析题&#xff0c;年均增长量 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申…