C++:MySQL数据库的增删改(三)
1、相关API
- 执行所有的sql语句都是mysql_query或者mysql_real_query
- mysql_query无法处理带有特殊字符的sql语句(如:反斜杠0)
- mysql_real_query则可以避免,一般使用这个。
- mysql_affected_rows:获取sql语句执行结果影响的行数
- mysql_insert_id:插入数据返回主键id值
- mysql_num_rows:获取select语句查询结果有多少条
my_ulonglong mysql_affected_rows(MYSQL *mysql);my_ulonglong mysql_insert_id(MYSQL *mysql);my_ulonglong mysql_num_rows(MYSQL_RES *res);
2、创增删改
2.1、连接MySQL数据库
#include <iostream>
#include <mysql/mysql.h>
#include <cstring>
#include <sstream>
#include <string>
#include <unordered_map>using namespace std;
int main(int argc, char *argv[])
{MYSQL mysql;// 初始化mysql结构体并且初始化服务连接环境mysql_init(&mysql);const char *host = "127.0.0.1";const char *user = "root";const char *password = "123456";const char *db = "cpp";int timeout = 3;// 连接超时时长设置mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);// 断开重连设置int reconnect = 1;mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);// MySQL连接建立if(!mysql_real_connect(&mysql, host, user, password, db, 3306, 0, 0)){std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;}else{std::cout << "mysql connect " << host << " success!" << std::endl;}mysql_close(&mysql);return 0;
}
2.1、创建一张表
void create_table(MYSQL &mysql)
{string sql = "CREATE TABLE IF NOT EXISTS `user` (\`id` int(10) unsigned NOT NULL AUTO_INCREMENT,\`username` varchar(255) NOT NULL,\`password` varchar(255) NOT NULL,\PRIMARY KEY (`id`)\) ENGINE=InnoDB DEFAULT CHARSET=utf8;";if(mysql_real_query(&mysql, sql.c_str(), sql.length()) != 0){cout << "mysql_query failed!" << endl;}
}
2.2、插入数据
void insert_data(MYSQL &mysql)
{string sql = "insert into `user`(`username`, `password`) values ('Splay', '123456');";if(mysql_real_query(&mysql, sql.c_str(), sql.length()) == 0){int affect_count = mysql_affected_rows(&mysql);cout << "insert data success, affect count = " << affect_count << ", id = " << mysql_insert_id(&mysql) << endl;}else{cout << "insert data failed! sql = " << sql << ", error msg = " << mysql_error(&mysql) << endl;}for(int i = 2;i <= 1000;i++){stringstream ss;ss << "insert into `user`(`username`, `password`) values ('Splay', '" << i << "_123456');";sql = ss.str();int insert_result = mysql_real_query(&mysql, sql.c_str(), sql.length());if(insert_result == 0){int affect_count = mysql_affected_rows(&mysql);cout << "insert data success, affect count = " << affect_count << ", id = " << mysql_insert_id(&mysql) << endl;}else{cout << "insert data failed! sql = " << sql << ", error msg = " << mysql_error(&mysql) << endl;}}
}
2.3、更改数据
void update_data(MYSQL &mysql)
{
// string sql = "update `user` set `username` = 'Admin', `password` = 'admin' where `id` = 1";
// int update_result = mysql_real_query(&mysql, sql.c_str(), sql.length());unordered_map<string, string> update_map;update_map["username"] = "Admin";update_map.insert(make_pair("password", "hello"));string sql = "update `user` set ";string condition = "where id < 10";for(auto it = update_map.begin();it != update_map.end();it++){sql += "`" + it->first + "` = '" + it->second + "', ";}sql += "`id` = id ";sql += condition;int update_result = mysql_real_query(&mysql, sql.c_str(), sql.length());if(update_result == 0){int affect_count = mysql_affected_rows(&mysql);cout << "update data success, affect count = " << affect_count << endl;}else{cout << "update data failed! sql = " << sql << ", error msg = " << mysql_error(&mysql) << endl;}
}
2.4、删除和清空
void delete_data_or_table(MYSQL& mysql)
{string sql = "delete from `user` where id = 1000"; // 删除id = 1000的数据
// string sql = "truncate table `user`"; // 清空整张表,主键从0开始
// string sql = "drop table `user`"; // 删除所有数据和整张表int delete_result = mysql_real_query(&mysql, sql.c_str(), sql.length());if(delete_result == 0){int affect_count = mysql_affected_rows(&mysql);cout << "delete data success, affect count = " << affect_count << endl;}else{cout << "delete data failed! sql = " << sql << ", error msg = " << mysql_error(&mysql) << endl;}
}
3、同时执行多条sql语句
-
C/C++也提供了通知允许多条语句的执行,查询、执行、结果集等
-
需要再创建连接是在最后的clientflag参数指定,默认并不支持
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */
#define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS mysql_real_connect(&mysql, host, user, password, db, 3306, 0, CLIENT_MULTI_QUERIES);
3.1、案例使用代码
- mysql_field_count:可以获取select查询到的字段数目,通过查询到的字段数目可以判断是否是select操作
- mysql_next_result:传入结果集MYSQL_RES *指针,返回-1表示没有下一条的执行结果反馈了,返回0表示有。
// MySQL连接建立if(!mysql_real_connect(&mysql, host, user, password, db, 3306, 0, CLIENT_MULTI_QUERIES)){std::cout << "mysql connect failed!" << mysql_error(&mysql) << std::endl;}else{std::cout << "mysql connect " << host << " success!" << std::endl;}// 1. 删除表、创建表string sql = "DROP TABLE IF EXISTS `user`;\CREATE TABLE IF NOT EXISTS `user` (\`id` int(10) unsigned NOT NULL AUTO_INCREMENT,\`username` varchar(255) NOT NULL,\`password` varchar(255) NOT NULL,\PRIMARY KEY (`id`)\) ENGINE=InnoDB DEFAULT CHARSET=utf8;";// 2. 增加1000条数据for(int i = 1;i <= 1000;i++){stringstream ss;ss << "insert into `user`(`username`, `password`) values ('Splay', '" << i << "_123456');";sql += ss.str();}// 3. 更改数据unordered_map<string, string> update_map;update_map["username"] = "Admin";update_map.insert(make_pair("password", "hello"));sql += "update `user` set ";for(auto it = update_map.begin();it != update_map.end();it++){sql += "`" + it->first + "` = '" + it->second + "', ";}sql += "`id` = id where id < 10;";// 4. 删除数据sql += "delete from `user` where id < 10;"; // 删除id = 1000的数据// 5. 查询数据sql += "select *from `user`;";int execute_result = mysql_real_query(&mysql, sql.c_str(), sql.length());if(execute_result != 0){cout << "execute multi statement error!" << mysql_error(&mysql) << endl;}cout << "mysql_next_result(&mysql) = " << mysql_next_result(&mysql) << endl;do{MYSQL_RES *result = mysql_store_result(&mysql);if(result){ // 结果集不为空表示select语句获得了查询结果cout << "select get result rows = " << mysql_num_rows(result) << endl;mysql_free_result(result);}else{if(mysql_field_count(&mysql)){ // select 有字段但是没有结果 ===> 查询出错cout << "Not Retrieve Result!" << endl;}else{ // update、delete、insert、truncate、drop、create...cout << "execute affect rows = " << mysql_affected_rows(&mysql) << endl;}}}while(mysql_next_result(&mysql) == 0);cout << "mysql_next_result(&mysql) = " << mysql_next_result(&mysql) << endl;
4、总结
C/C++操纵数据库的方式便捷性太差,虽然JDBC的也很烂,但是JDBC有开源的ORM框架(mybatis、jooq、hiberate、springdata…),不敢想象如果全裸使用C/C++写一些业务会有多痛苦,捂脸!
相关文章:
C++:MySQL数据库的增删改(三)
1、相关API 执行所有的sql语句都是mysql_query或者mysql_real_query mysql_query无法处理带有特殊字符的sql语句(如:反斜杠0)mysql_real_query则可以避免,一般使用这个。 mysql_affected_rows:获取sql语句执行结果影响…...
golang - 简单实现linux上的which命令
本文提供了在环境变量$PATH设置的目录里查找符合条件的文件的方法。 实现函数 import ("fmt""os""path""strings" )// 实现 unix whtich 命令功能 func Which(cmd string) (filepath string, err error) {// 获得当前PATH环境变量en…...
推荐一个好用的数据库映射架构
SqlSugar ORM 优点: SqlSugar 是 .NET 开源 ORM 框架,由 Fructose 大数据技术团队维护和更新,是开箱即用最易用的 ORM 优点: 【低代码】【高性能】【超简单】【功能综合】【多数据库兼容】【适用产品】 支持 .NET .NET framework.net core3.1.ne5.net6.net7.net8 .net…...
(013)window的Idea运行程序 Amazon java.nio.file.AccessDeniedException
解决方法一 在资源管理器中删除该目录, 在程序中使用代码,重新建立该目录: if (!FileUtil.exist(destinationPath)){FileUtil.mkdir(destinationPath); }解决方法二 JDK 的版本有问题,换个JDK。 解决方法三 网络不好…...
LeetCode 1684. 统计一致字符串的数目
解题思路 首先用set把allowed中的字符保存,然后一一判断。 相关代码 class Solution {public int countConsistentStrings(String allowed, String[] words) {Set<Character> set new HashSet<>();int reswords.length;for(int i0;i<allowed.len…...

uniapp-设置UrlSchemes从外部浏览器H5打开app
需求:外部浏览器H5页面,跳转到uniapp开发的原生app内部。 1、uniapp内部的配置: (1)打开manifest->App常用其他设置,如下,按照提示输入您要设置的urlSchemes: (2&am…...

校园圈子小程序,大学校园圈子,三段交付,源码交付,支持二开
介绍 在当今的数字化时代,校园社交媒体和在线论坛成为了学生交流思想、讨论问题以及分享信息的常用平台。特别是微信小程序,因其便捷性、用户基数庞大等特点,已逐渐成为构建校园社区不可或缺的一部分。以下是基于现有资料的校园小程序帖子发…...

基于kmeans的聚类微博舆情分析系统
第一章绪论 1.1研究背景 如今在我们的生活与生产的每个角落都可以见到数据与信息的身影。自从上十世纪八十年代的中后期开始,我们使用的互联网技术已经开始快速发展,近些年来云计算、大数据和物联网等与互联网有相领域的发展让互联网技术达到了史无前例…...
【Docker常用命令(四)】
目录 Docker常用命令(四)注意 Docker常用命令(四) docker pause docker pause 命令用于暂停容器中的所有进程。docker pause CONTAINER [CONTAINER...]常用子命令和选项:无特定常用选项。docker port docker port 命令…...
黑豹程序员-Spring Task实现定时任务
定时任务 项目中,我们有一个特殊的要求,无需人为去触发,而是自动去触发程序。通常有一定的频率,每天,某时等。 实现的四种方式 1、java自身提供定时任务java.util.Timer类,但太过简单,几乎无…...

云原生安全当前的挑战与解决办法
云原生安全作为一种新兴的安全理念,不仅解决云计算普及带来的安全问题,更强调以原生的思维构建云上安全建设、部署与应用,推动安全与云计算深度融合。所以现在云原生安全在云安全领域越来受到重视,云安全厂商在这块的投入也是越来…...
Qt——Qt实现数据可视化之QChart的使用总结(使用QChart画出动态显示的实时曲线)
【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》...

(React生命周期)前端八股文修炼Day8
一 React的生命周期有哪些 React组件的生命周期可以分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。React类组件的生命周期方法允许你在组件的不同阶段执行代码。 挂载…...

考研||考公||就业||其他?-------愿不再犹豫
大三下了,现在已经开学一个多月了,在上个学期的时候陆陆续续吧周围有的行动早的人已经开始准备考研了,当然这只是下小部分人吧,也有一部分人是寒假可能就开始了,更多的则是开学的时候,我的直观感受是图书馆…...
使用 Selenium 和 OpenCV 识别验证码(使用 Java)
验证码的自动识别对于爬虫来说是一个常见的挑战。在这篇文章中,我们将展示如何使用 Selenium 和 OpenCV,结合 Java,来自动化识别网站上的验证码。 配置 Maven 依赖 首先,我们需要在 Maven 项目中添加 Selenium 和 OpenCV 的依赖。…...

什么是数据库?如何安装SQL Server(超详细版)
文章目录 什么是数据库数据库与数据库管理系统数据库系统之间的区别和联系数据库在生活中的应用 安装SQL Server数据库系统要求 安装步骤(超详细)安装前的准备 安装SSMS 什么是数据库 数据库,顾名思义,是存储数据的“仓库”。它不仅仅是简单的数据存储&…...

Golang 开发实战day08 - Multiple Return values
Golang 教程08 - Multiple Return values 1. Multiple return values 1.1 如何理解多个返回值? Go语言中的多返回值,就像你听了一首歌曲yellow,可以从歌曲里反馈出忧郁和害羞!Goland的多个返回值就类似于如此,设定一…...

如何成为一名优秀的工程师下
身为工程师,理所当然要重视实践,自然科学不管发展到何时都离不开实验。 电子学本身就是 为了指导工程实践。所以不要谈空洞的理论。现在很多毕业生都面临这样的问题,总是谈一些空洞的理论,甚至错误的但还不以为然的理论。实践可以…...
Docker【1】:Docker制作Oracle19C镜像
Docker【1】:Docker制作Oracle19C镜像 1、参考官方文档2、下载相关文件2.1、工具包2.2、Oracle安装包 3、制作镜像3.1、拷贝下载的oracle安装包到制作工具对应版本目录下3.2、开始制作镜像包3.3、制作完成 4、导出导入镜像4.1、镜像导出4.2、镜像导入 5、运行Oracle…...

Layui三级联动插件使用方法
Layui高版本中没有在提供三级联动这个动画了,而是封装成了一个插件,使用方式也很简单 官网 省市县区三级联动下拉选择器 layarea - Layui 第三方扩展组件平台 (layuion.com)https://dev.layuion.com/extend/layarea/#doc html页面约束 整个选择器需要…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...