01-线程池项目背景:C++的数据库操作

从0开始学习C++与数据库的联动

1.原始方式-使用MySQL Connector/C 提供的API查询

1.1 数据库预操作

我的本地电脑上有mysql数据库,里面预先创建了一个database名叫chat,用户名root,密码password。

1.2 Visual Studio预操作

在Windows上使用VS需要加一些路径之类的,这样才可以使用MySQL C API。否则,无法找到mysql.h,无法正常链接dll、lib,无法编译。
1.下载MySQL Connector/C;
2.配置包含目录和库目录:
“C/C++” -> “常规” -> “附加包含目录”,添加MySQL Connector/C的include目录。
“链接器” -> “常规” -> “附加库目录”,添加MySQL Connector/C的lib目录。
3.配置链接库:
在“链接器” -> “输入” -> “附加依赖项”,添加以下库文件:
libmysql.lib:MySQL C API的静态库。
mysqlclient.lib:MySQL C API的动态链接库。
4.拷贝运行时依赖项: 将MySQL Connector/C的bin目录添加到系统的PATH环境变量中,并将libmysql.dll文件复制到vcxproj文件所在的目录。

1.3 简单查询程序

1.下面是一个单线程的程序,所有的数据库连接和查询都是在主线程中执行的。(里面可能有一些不安全的操作,方便理解没有管,比如close函数里传nullptr是不安全的,NULL最好改成nullptr便于与0值区分等。)
2.mysql.h声明了MYSQL、MYSQL_ROW、MYSQL_RES等结构体和一些mysql_init这样的函数,必须包含这个头文件,编译才不会出错。
从https://dev.mysql.com/doc/c-api/8.0/en/c-api-basic-function-reference.html摘了一些出来,可跳转链接看具体的接口参数
结构体:
在这里插入图片描述
函数接口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <mysql.h> // 假设使用MySQL数据库int main() {// 步骤1:建立数据库连接MYSQL* conn = mysql_init(NULL);if (conn == NULL) {std::cerr << "Failed to initialize MySQL connection." << std::endl;return -1;}if (mysql_real_connect(conn, "localhost", "root", "password", "chat", 0, NULL, 0) == NULL) {std::cerr << "Failed to connect to MySQL database." << std::endl;mysql_close(conn);return -1;}// 步骤2:执行SQL查询const char* query = "SELECT * FROM user";if (mysql_query(conn, query) != 0) {std::cerr << "Failed to execute SQL query." << std::endl;mysql_close(conn);return -1;}MYSQL_RES* result = mysql_store_result(conn);if (result == NULL) {std::cerr << "Failed to store MySQL result." << std::endl;mysql_close(conn);return -1;}// 处理查询结果MYSQL_ROW row;while ((row = mysql_fetch_row(result)) != NULL) {// 处理每一行的数据std::cout << "Column 1: " << row[0] << ", Column 2: " << row[1] << std::endl;}// 释放查询结果mysql_free_result(result);// 步骤3:断开数据库连接mysql_close(conn);return 0;
}

2.将上述API查询封装到类里,调用自己的函数查询

上面的代码主要是用到了mysql_init,mysql_real_connect,mysql_query,mysql_store_result,mysql_free_result,mysql_close这些mysql.h里声明的一些函数。如果我们想用这些函数进行对MYSQL数据库内数据的操作,用的是MYSQL*类型的指针conn进行操作。

  1. 首先,MYSQL* conn = mysql_init(NULL);也即真正malloc了一个空间,分配和初始化了一个 MYSQL 结构体实例,并返回指向该实例的指针conn。这个实例用于存储数据库连接所需的所有信息。
  2. mysql_real_connect 函数建立实际的数据库连接,并使用 MYSQL 结构体来保存连接的详细信息。
  3. 之后,无论是查询(mysql_query)、获取结果(mysql_store_result)还是关闭连接(mysql_close),都需要使用这个 MYSQL* 类型的指针。这是因为所有这些操作都是在特定的数据库连接会话上执行的,而 conn 指针正是指向这个会话的。

那么,在此基础之上,我们可以将这些函数进一步的封装,用一个类中的成员函数去分别调用它们。具体而言,我们自己定义一个Connection类,里面放一个私有成员对象MYSQL* _conn指针,以及构造、析构、连接、更新、查询函数,而这些函数又分别调用了初始的mysql_init,mysql_real_connect,mysql_query,mysql_store_result,mysql_free_result,mysql_close这些mysql.h里声明的一些函数,调用的参数是初始函数所需的参数加上conn指针。在我们自己实现的函数里,还可以额外加一些LOG语句。当我们对这个类进行实例化的时候,用类实例.成员函数()就可以真正对数据库进行增删改查。

代码分为4个文件,Connection.h、Connection.cpp、main.cpp,以及最简单的日志打印(仅仅使用了一个宏,而未用到任何日志库。)里面把之前的store换成了use,这样可以减轻内存的使用,直接按行输出而不用保存。

Connection.cpp:

// 实现对数据库的增删改查
#pragma once
#include <iostream>
#include "Connection.h"
#include "public.h"//构造函数    mysql_init 函数用于初始化一个新的 MYSQL 结构体实例。这是建立数据库连接之前的准备步骤。
//分配并初始化一个新的 MYSQL 结构体,返回一个指向这个新结构体的指针;如果分配失败,返回 NULL。
Connection::Connection() {_conn = mysql_init(nullptr);
}//真正的连接
bool Connection::connect(string ip, string user, string password, string dbname, unsigned short port) {MYSQL* p = mysql_real_connect(_conn,ip.c_str(), user.c_str(), password.c_str(), dbname.c_str(), port, nullptr, 0);//.c_str() :将string转换为 const char* 类型return p != nullptr;
}//增删改,只要返回bool的一些操作
bool Connection::update(string sql) {if (mysql_query(_conn, sql.c_str())) {//当 mysql_query() 返回 0 时,表示查询语句成功执行LOG("更新失败:" + sql);return false;}return true;
}//查并返回结果,实际上就是存
MYSQL_RES* Connection::query(string sql) {if (mysql_query(_conn, sql.c_str())) {LOG("查询失败:" + sql);return nullptr;}return mysql_use_result(_conn);
}//析构函数(关闭连接)
Connection::~Connection() {if (_conn != nullptr)mysql_close(_conn);
}

Connection.h:

// 实现对数据库的增删改查
#pragma once
#include <mysql.h>
#include <string>
using namespace std;class Connection {
public:Connection();~Connection();	//析构函数(关闭连接)bool connect(string ip, string user, string password, string dbname, unsigned short port);	//真正的连接bool update(string sql);	//增删改,只要返回bool的一些操作MYSQL_RES* query(string sql);	//查并返回结果,实际上就是存private:MYSQL* _conn;
};

public.h:

#pragma once
#define LOG(str)\cout<<__FILE__<<":"<<__LINE__<<" "<<__TIMESTAMP__<<":"<<str<<endl;

main:

#include "Connection.h"int main() {Connection conn;conn.connect("localhost", "root", "password", "chat", 3306);string sql = "insert into user (name, age, sex) values ('zhang san' ,18, 'male');";conn.update(sql);
//这里没有测试queryreturn 0;
}

在这里插入图片描述
可以发现原本chat database里面user表里没有数据的,执行了该程序之后成功插入了一行数据。并且,id一开始设置成了自增字段,就没有手动指定,只插入了(name, age, sex),它会自动从1开始填。

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

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

相关文章

JavaScript 基础三part1.数组

JavaScript 基础三part1.数组 2.1 数组是什么2.2 数组的基本使用&#xff08;1&#xff09;声明&#xff08;2&#xff09;取值&#xff08;3&#xff09;一些术语&#xff08;4&#xff09;遍历数组 2.3 操作数组&#xff08;1&#xff09;修改&#xff08;2&#xff09;新增&…

x-cmd pkg | doggo - 现代化的 DNS 客户端

目录 简介首次用户快速实验指南功能特点类似工具与竞品进一步探索 简介 doggo 是一个由 Karan Sharma 于 2020 年使用 Go 语言开发的 DNS 客户端。它类似于 dig 命令&#xff0c;但旨在以现代化、简洁和可读的格式输出 DNS 查询结果。 首次用户快速实验指南 使用 x doggo 即可…

工作中人员离岗识别摄像机

工作中人员离岗识别摄像机是一种基于人工智能技术的智能监控设备&#xff0c;能够实时识别员工离岗状态并进行记录。这种摄像机通常配备了高清摄像头、深度学习算法和数据处理系统&#xff0c;可以精准地监测员工的行为&#xff0c;提高企业的管理效率和安全性。 工作中人员离岗…

SSM建材商城网站----计算机毕业设计

项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录,管理员管理,注册用户管理,新闻公告管理,建材类型管理,配货点管理,建材商品管理,建材订单管理,建材评价管理等功能。 用…

低代码UI构件程序设计基础实训一

步骤一 低代码在线调试工具 网址 低代码在线调试工具 步骤二 D盘建一个文件夹&#xff0c;文件夹下建两个文件夹ico和js 网上找一些图片&#xff0c;后缀.png&#xff0c;编号从0开始&#xff0c;图片另存到ico文件夹下 下载&#xff08;右键另存为&#xff09;以下四个页面…

【面试高频算法解析】算法练习6 广度优先搜索

前言 本专栏旨在通过分类学习算法&#xff0c;使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目&#xff0c;帮助您深度理解每种算法&#xff0c;避免出现刷了很多算法题&#xff0c;还是一知半解的状态 专栏导航 二分查找回溯&#xff08;Backtracking&…

AI大模型与低代码开发应用的完美融合

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术的快速发展引领了许多创新的应用&#xff0c;而大型AI模型和低代码开发平台是这一进展的两个重要方面。本文将探讨AI大模型与低代码开发应用的关系&#xff0c;以及如何利用它们共同推动技术创新和业务发展。 AI大模型…

Flowable6.8适配人大金仓 达梦

目录 前言 一、Flowable6.8 适配人大金仓 1.引入postgreSQL依赖 2.配置驱动 3.总结 二&#xff0c;Flowable 6.8 适配DMV8 1.引入达梦依赖 2.配置数据库 3.确认liquibase的版本 4.liquibase4.x的适配步骤 4.1 在项目中新建liquibase.database.core 包 4.2 创建Oracl…

如何实现无人机识别功能

无人机识别算法可以基于不同的传感器和技术&#xff0c;结合多种方法进行实现。以下是一些常见的无人机识别算法和技术&#xff1a; 视觉识别&#xff1a; 图像处理&#xff1a; 使用计算机视觉技术对无人机图像进行处理&#xff0c;包括特征提取、目标检测和跟踪等。深度学习&…

【模拟电路】软件Circuit JS

一、模拟电路软件Circuit JS 二、Circuit JS软件配置 三、Circuit JS 软件 常见的快捷键 四、Circuit JS软件基础使用 五、Circuit JS软件使用讲解 欧姆定律电阻的串联和并联电容器的充放电过程电感器和实现理想超导的概念电容阻止电压的突变&#xff0c;电感阻止电流的突变LR…

年度最整洁的海盗3.0版本

在修改海盗3.0客户端源码的时候&#xff0c;一直都存在这样的一个问题&#xff1a; 客户端在某些特定的情况下&#xff0c;会报内存错误导致程序崩溃。 经过调试&#xff0c;发现是那个MindPower3D的dll&#xff0c;在跳转地图等情况下卸载清理内存的时候&#xff0c;会偶发出…

pod进阶版(1)

pod的相关知识 k8s的pad重启策略: Always deployment的yaml文件只能是Always pod的yaml三种模式都可以。 Onfailure:只有异常退出状态码非0才会重启。正常退出不重启。 Never&#xff1a;非正常退出和非正常退出都不重启。 容器的退出了pod才会重启。 pod可以有多个容器&…