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页面约束 整个选择器需要…...
【Midjourney×Photoshop黄金工作流】:20年Adobe+AI实战专家亲授5步无缝整合法,97%设计师尚未掌握的智能修图新范式
更多请点击: https://intelliparadigm.com 第一章:MidjourneyPhotoshop黄金工作流的范式革命 传统图像创作正经历一场静默却深刻的重构——当 Midjourney 生成的高语义图像与 Photoshop 的像素级控制能力深度耦合,工作流不再只是“AI出图→人…...
避坑指南:STM32CubeMX配置红外接收,为什么你的解码总是不准?
STM32CubeMX红外接收解码优化实战:从原理到精准解析 红外遥控技术在家电控制、智能设备交互中扮演着重要角色,但许多开发者在STM32平台上实现红外接收解码时,常遇到信号不稳定、误码率高等问题。本文将深入分析红外接收解码的核心原理&#…...
光纤偏振测量:从琼斯矢量到庞加莱球,六种工具深度解析与工程实践
1. 从一道周五小测题说起:光纤测量中的偏振态表征上周五,我在整理旧资料时,翻到了EE Times在2015年发布的一篇“周五小测”文章,主题是光纤光学测量。其中第一道题就很有意思,它问的是:“以下哪种工具不能用…...
[具身智能-679]:ROS2功能包 - 命令行与系统工具概述与使用示例
这是 ROS2 开发每天必用 的工具,全部通过终端命令操作,用于调试、查看、控制、记录整个 ROS2 系统。我按最常用顺序给你整理,每条命令都能直接复制运行。一、核心工具组:ros2cli所有命令都以 ros2 开头,是 ROS2 的总控…...
用MATLAB和Vivado搞个带通FIR滤波器:从FDATool到IP核的完整配置流程
从MATLAB到FPGA:带通FIR滤波器的工程化实现全指南 在数字信号处理领域,FIR滤波器因其线性相位特性和稳定性成为工程师的首选工具。当我们需要从高速采样信号中提取特定频段时,带通FIR滤波器的设计就变得尤为关键。本文将带您完整走通从MATLAB…...
别再只盯着原理图了!用Python+OpenCV动手模拟激光三角测距(斜射/直射对比)
用PythonOpenCV模拟激光三角测距:斜射与直射的实战对比 激光三角测距技术听起来高大上,但真正理解它的精髓往往需要跳出公式推导的泥潭。作为一名长期在工业检测领域摸爬滚打的技术人员,我发现用代码模拟物理过程是最有效的学习方式。本文将…...
告别ST-LINK Utility!STM32CubeProg保姆级安装指南(含Java环境配置与常见报错解决)
从ST-LINK Utility到STM32CubeProg:嵌入式开发者的无缝迁移实战手册 当ST官方宣布STM32CubeProg将全面取代ST-LINK Utility时,许多习惯了旧工具的开发者都面临着一个现实问题:如何在不中断项目进度的情况下完成工具链的平稳过渡?作…...
如何快速上手Unitree Go2 ROS2 SDK:模块化机器人开发完整指南
如何快速上手Unitree Go2 ROS2 SDK:模块化机器人开发完整指南 【免费下载链接】go2_ros2_sdk Unofficial ROS2 SDK support for Unitree GO2 AIR/PRO/EDU 项目地址: https://gitcode.com/gh_mirrors/go/go2_ros2_sdk Unitree Go2 ROS2 SDK是为宇树科技GO2系列…...
群晖相册AI识别解锁指南:让无GPU设备也能享受智能相册功能
群晖相册AI识别解锁指南:让无GPU设备也能享受智能相册功能 【免费下载链接】Synology_Photos_Face_Patch Synology Photos Facial Recognition Patch 项目地址: https://gitcode.com/gh_mirrors/sy/Synology_Photos_Face_Patch 你是否拥有DS918或DS3615xs等群…...
45.什么是内联条件表达式(inline conditional expressions)?在事件处理里怎么用?
内联条件表达式指的是:你在 JSX 里直接用 JavaScript 条件语法(如三元 ? :、逻辑与 &&、逻辑或 ||)来决定事件处理函数是否执行、执行哪段逻辑,或给事件处理器提供一个默认值。它能让事件行为跟 props/state 动态绑定&am…...
