MySQL 数据库编程-C++
目录
1 数据库基本知识
1.1 MYSQL常见命令
1.2 SQL注入
1.3 ORM框架
1 数据库基本知识
MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个关系型数据库由一个或数个表格组成:
- 数据库: 数据库是一些关联表的集合。
- 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
- 列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
- 行:一行(元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
1.1 MYSQL常见命令
1.连接mysql:mysql -u root -p*****
2.创建数据库:create DTATBASE myDB
/*
CREATE DATABASE mydatabase -- 创建名为 "mydatabase" 的数据库CHARACTER SET utf8mb4 -- 设置字符集为 utf8mb4,比utf8高级,支持表情字符COLLATE utf8mb4_general_ci; -- 设置校对规则为 utf8mb4_general_ci,大小写不敏感
*/
/*
如果数据库已经存在,执行 CREATE DATABASE 将导致错误。
为了避免这种情况,你可以在 CREATE DATABASE 语句中添加 IF NOT EXISTS 子句:
CREATE DATABASE IF NOT EXISTS mydatabase;
*/
3.删除数据库:DROP DATABASE RUNOOB;
4.选择数据库,后续操作只针对这个数据库:USE database_name;/mysql -u your_username -p -D your_database
5.创建数据表:
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL,birthdate DATE,is_active BOOLEAN DEFAULT TRUE
);
/*
id: 用户 id,整数类型,自增长,作为主键。
username: 用户名,变长字符串,不允许为空。
email: 用户邮箱,变长字符串,不允许为空。
birthdate: 用户的生日,日期类型。
is_active: 用户是否已经激活,布尔类型,默认值为 true。
*/
6.删除数据表:DROP TABLE [IF EXISTS] table_name; //外键约束:如果该表与其他表有外键约束,可能需要先删除外键约束,或者确保依赖关系被处理好。
7.插入数据:
INSERT INTO users (username, email, birthdate, is_active)
VALUES('test1', 'test1@runoob.com', '1985-07-10', true),('test2', 'test2@runoob.com', '1988-11-25', false),('test3', 'test3@runoob.com', '1993-05-03', true);
8.查询数据:
SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column_name [ASC | DESC]]
[LIMIT number];
9.更新数据:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
/*
table_name 是你要更新数据的表的名称。
column1, column2, ... 是你要更新的列的名称。
value1, value2, ... 是新的值,用于替换旧的值。
WHERE condition 是一个可选的子句,用于指定更新的行。如果省略 WHERE 子句,将更新表中的所有行。
*/
20.删除数据:
DELETE FROM table_name
WHERE condition;
/*
table_name 是你要删除数据的表的名称。
WHERE condition 是一个可选的子句,用于指定删除的行。如果省略 WHERE 子句,将删除表中的所有行。
*/
21.LIKE子句:用于在 WHERE 子句中进行模糊匹配的关键字。它通常与通配符%一起使用,用于搜索符合某种模式的字符串
SELECT column1, column2, ...
FROM table_name
WHERE column_name LIKE pattern;
22.UNION操作符:用于连接两个以上的 SELECT 语句的结果组合到一个结果集合,并去除重复的行。
SELECT column1, column2, ...
FROM table1
WHERE condition1
UNION
SELECT column1, column2, ...
FROM table2
WHERE condition2
[ORDER BY column1, column2, ...];
23.ORDER BY(排序) 语句:按照一个或多个列的值进行升序(ASC)或降序(DESC)排序。
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
1.2 SQL注入
所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。
MySQL 注入是指攻击者通过恶意构造的输入,成功地执行恶意的 SQL 查询,这通常发生在用户输入未经适当验证或转义的情况下,攻击者试图在输入中插入 SQL 代码,以执行意外的查询或破坏数据库。
例如,用户输入:
SELECT * FROM users WHERE username = 'input_username' AND password = 'input_password';
//如果没有正确的输入验证和防范措施,攻击者可以输入类似于以下内容的用户名:
' OR '1'='1'; --
// 在这种情况下,SQL 查询会变成:
SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = 'input_password';
//这会使查询返回所有用户,因为 1=1 总是为真,注释符号 -- 用于注释掉原始查询的其余部分,以确保语法正确。
防止SQL注入的方法:
- 使用参数化查询或预编译语句: 使用参数化查询(Prepared Statements)可以有效防止 SQL 注入,因为它们在执行查询之前将输入数据与查询语句分离。
- 输入验证和转义: 对用户输入进行适当的验证,并使用合适的转义函数(如
mysqli_real_escape_string)来处理输入,以防止恶意注入。 - 最小权限原则: 给予数据库用户最小的权限,确保它们只能执行必要的操作,以降低潜在的损害。
- 使用ORM框架: 使用对象关系映射(ORM)框架(如Hibernate、Sequelize)可以帮助抽象 SQL 查询,从而降低 SQL 注入的风险。
- 禁用错误消息显示: 在生产环境中,禁用显示详细的错误消息,以防止攻击者获取有关数据库结构的敏感信息。
1.3 ORM框架
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM框架是连接数据库的桥梁,只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。
也就是将数据库的一张表映射为一个类,表的字段就是这个类的成员变量。

为什么使用ORM?
其一可以有效防止SQL注入;其二可以实现业务层和数据层的解耦,在实现数据库CRUD操作过程中存在大量重复的SQL语句,调用类对象的方法可以有效减少重复性代码。
优点:
1)提高开发效率,降低开发成本
2)使开发更加对象化
3)可移植
4)可以很方便地引入数据缓存之类的附加功能
缺点:
1)自动化进行关系数据库的映射需要消耗系统性能,一般来说都可以忽略。
2)在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。
示例:
db.cpp定义数据库连接、更新、查询操作;
user.hpp定义表字段;
usermodel.cpp实现表具体操作。
#include"db.h"
#include<muduo/base/Logging.h>
//数据库配置信息
static string server = "127.0.0.1";
static string user = "root";
static string password = "123456";
static string dbname = "chat";//初始化数据库连接,为连接开辟资源
MySQL::MySQL()
{_conn = mysql_init(nullptr);
}//释放数据库连接资源
MySQL::~MySQL()
{if(_conn!=nullptr){mysql_close(_conn);}
}//连接数据库
bool MySQL::connect()
{MYSQL *p = mysql_real_connect(_conn, server.c_str(), user.c_str(), password.c_str(),dbname.c_str(), 3306, nullptr, 0);if (p != nullptr){// C和C++代码默认的编码字符是ASCII,如果不设置,从Mysql上拉取的数据不支持汉字mysql_query(_conn, "set names gbk");LOG_INFO << "connect mysql success!";}else{LOG_INFO << "connect mysql fail!";}return p;
}//更新操作
bool MySQL::update(string sql)
{if (mysql_query(_conn, sql.c_str())){LOG_INFO << __FILE__ << ":" << __LINE__ << ":"<< sql << "更新失败!";return false;}return true;
}//查询操作
MYSQL_RES* MySQL::query(string sql)
{if (mysql_query(_conn, sql.c_str())){LOG_INFO << __FILE__ << ":" << __LINE__ << ":"<< sql << "查询失败!";return nullptr;}return mysql_use_result(_conn);
}//获取连接
MYSQL *MySQL::getConnection()
{return _conn;
}
#ifndef USER_H
#define USER_H#include<string>
using namespace std;
/*
mysql> SHOW COLUMNS FROM user;
+----------+--------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(50) | NO | UNI | NULL | |
| password | varchar(50) | NO | | NULL | |
| state | enum('online','offline') | YES | | offline | |
+----------+--------------------------+------+-----+---------+----------------+
*/
//定义数据库对象,将数据库信息整合为一个对象提交给业务层
//匹配User表的ORM类
class User{
public:User(int id = -1, string name = "", string pwd = "", string state = "offline"){this->id = id;this->name = name;this->password = pwd;this->state = state;}void setId(int id){this->id = id;}void setName(string name){this->name = name;}void setPwd(string pwd){this->password = pwd;}void setState(string state){this->state = state;}int getId(){return this->id;}string getName(){return this->name;}string getPwd(){return this->password;}string getState(){return this->state;}
private:int id;string name;string password;string state;
};
#endif
#include"usermodel.hpp"
#include"db.h"
#include<iostream>
#include<muduo/base/Logging.h>
using namespace std;
//User表的增加方法
bool UserModel::insert(User &user)
{//1. 组成sql语句char sql[1024] = {0};sprintf(sql, "insert into user(username,password,state) values('%s', '%s', '%s')",user.getName().c_str(), user.getPwd().c_str(), user.getState().c_str());LOG_INFO<<sql;//2.连接数据库MySQL mysql;if (mysql.connect()){if(mysql.update(sql)){//获取插入成功的用户数据生成的主键iduser.setId(mysql_insert_id(mysql.getConnection()));return true;}}return false;
}
相关文章:
MySQL 数据库编程-C++
目录 1 数据库基本知识 1.1 MYSQL常见命令 1.2 SQL注入 1.3 ORM框架 1 数据库基本知识 MySQL 为关系型数据库(Relational Database Management System), 这种所谓的"关系型"可以理解为"表格"的概念, 一个关系型数据库由一个或数个表格组成:…...
【大数据技术】搭建完全分布式高可用大数据集群(Flume)
搭建完全分布式高可用大数据集群(Flume) apache-flume-1.11.0-bin.tar.gz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群 Flume 的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/software目录下,软件安装至/opt目…...
疯狂前端面试题(二)
一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源(JavaScript、CSS、图片、字体等)视为模块,并通过依赖关系图将这些模块打包成一个或多个最终的输出文件(通常是一个或几个…...
kafka专栏解读
kafka专栏文章的编写将根据kafka架构进行编写,即先编辑kafka生产者相关的内容,再编写kafka服务端的内容(这部分是核心,内容较多,包含kafka分区管理、日志存储、延时操作、控制器、可靠性等),最后…...
深入探究 C++17 std::is_invocable
文章目录 一、引言二、std::is_invocable 概述代码示例输出结果 三、std::is_invocable 的工作原理简化实现示例 四、std::is_invocable 的相关变体1. std::is_invocable_r2. std::is_nothrow_invocable 和 std::is_nothrow_invocable_r 五、使用场景1. 模板元编程2. 泛型算法 …...
OpenCV:图像修复
目录 简述 1. 原理说明 1.1 Navier-Stokes方法(INPAINT_NS) 1.2 快速行进方法(INPAINT_TELEA) 2. 实现步骤 2.1 输入图像和掩膜(Mask) 2.2 调用cv2.inpaint()函数 2.3 完整代码示例 2.4 运行结果 …...
【项目日记(四)】thread cache 层
前言 前面我们对整个项目的框架进行了介绍,本期开始我们将进行第一层线程缓存层(thread cache)的详细介绍与实现。 目录 前言 一、thread cache 的整体设计 二、内存对齐规则和哈希映射关系 2.1 如何对齐? 2.2 这样设计对齐规则的好处?…...
人工智能图像分割之Mask2former源码解读
环境搭建: (1)首先本代码是下载的mmdetection-2022.9的,所以它的版本要配置好,本源码配置例如mmcv1.7,python3.7,pytorch1.13,cuda11.7。pytorch与python,cuda版本匹配可参考:https://www.jb51.net/python/3308342lx.htm。 (2)还有一个是先要安装一个vs2022版本或…...
uniapp 编译生成鸿蒙正式app步骤
1,在最新版本DevEco-Studio工具新建一个空项目并生成p12和csr文件(构建-生成私钥和证书请求文件) 2,华为开发者平台 根据上面生成的csr文件新增cer和p7b文件,分发布和测试 3,在最新版本DevEco-Studio工具 文…...
2024最新版Java面试题及答案,【来自于各大厂】
发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了,需要完整版的及Java面试宝典小伙伴点赞转发,关注我后在【翻到最下方,文尾点击名片】即可免费获取…...
Excel 融合 deepseek
效果展示 代码实现 Function QhBaiDuYunAIReq(question, _Optional Authorization "Bearer ", _Optional Qhurl "https://qianfan.baidubce.com/v2/chat/completions")Dim XMLHTTP As ObjectDim url As Stringurl Qhurl 这里替换为你实际的URLDim postD…...
【填坑】新能源汽车三电设计之常用半导体器件系统性介绍
# 在新能源汽车的三电(电池、电机、电控)系统中,半导体器件扮演着至关重要的角色。它们如同系统的“大脑”和“神经末梢”,精确地控制着电能的流向与转换,确保新能源汽车高效、稳定且安全地运行。今天,就让…...
SpringCloud面试题----Nacos和Eureka的区别
功能特性 服务发现 Nacos:支持基于 DNS 和 RPC 的服务发现,提供了更为灵活的服务发现机制,能满足不同场景下的服务发现需求。Eureka:主要基于 HTTP 的 RESTful 接口进行服务发现,客户端通过向 Eureka Server 发送 HT…...
21.2.6 字体和边框
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 通过设置Rang.Font对象的几个成员就可以修改字体,设置Range.Borders就可以修改边框样式。 【例 21.6】【项目ÿ…...
正则表达式进阶(二)——零宽断言详解:\b \B \K \z \A
在正则表达式中,零宽断言是一种非常强大的工具,能够在不消费字符的情况下对匹配位置进行约束。除了环视(lookahead 和 lookbehind)以外,还有一些常用的零宽断言,它们用于处理边界、字符串的开头和结尾等特殊…...
OpenFeign远程调用返回的是List<T>类型的数据
在使用 OpenFeign 进行远程调用时,如果接口返回的是 List 类型的数据,可以通过以下方式处理: 直接定义返回类型为List Feign 默认支持 JSON 序列化/反序列化,如果服务端返回的是 List的JSON格式数据,可以直接在 Feig…...
三维模拟-机械臂自翻车
机械仿真 前言效果图后续 前言 最近在研究Unity机械仿真,用Unity实现其运动学仿真展示的功能,发现一个好用的插件“MGS-Machinery-master”,完美的解决了Unity关节定义缺少液压缸伸缩关节功能,内置了多个场景,讲真的&…...
网络安全治理架构图 网络安全管理架构
网站安全攻防战 XSS攻击 防御手段: - 消毒。 因为恶意脚本中有一些特殊字符,可以通过转义的方式来进行防范 - HttpOnly 对cookie添加httpOnly属性则脚本不能修改cookie。就能防止恶意脚本篡改cookie 注入攻击 SQL注入攻击需要攻击者对数据库结构有所…...
调用deepseek的API接口使用,对话,json化,产品化
背景 最近没咋用chatgpt了,deepseek-r1推理模型写代码质量是很高。deepseek其输出内容的质量和效果在国产的模型里面来说确实算是最强的,并且成本低,它的API接口生态也做的非常好,和OpenAI完美兼容。所以我们这一期来学一下怎么调…...
omegaconf库使用实践
最近在重构RapidOCR仓库代码,使其更加优雅的同时,具有扩展性。无意从他人源码中发现omegaconf库。 omegaconf OmegaConf是一个用于处理配置文件和命令行参数的Python库。它支持YAML、JSON、INI等多种配置文件格式,提供了配置合并、类型安全…...
STM32 USART1 串口调试打印,映射printf函数
该代码可以在freertos中正常运行,你可以进行更多细节优化 PA9(TX) PA10(RX) #include "usart.h"// 解决串口死机问题 #pragma import(__use_no_semihosting) struct __FILE { int handle; }; // 标准库需要的支持函数 FILE __…...
DeepSeek大模型本地部署实战
1. 下载并安装Ollama 打开浏览器:使用你常用的浏览器(如Chrome、Firefox等)访问Ollama的官方网站。无需特殊网络环境,直接搜索“Ollama”即可找到。 登录与下载:进入Ollama官网后,点击右上角的“Download…...
【学习总结|DAY037】Linux 项目部署
引言 在当今的软件开发领域,Linux 以其安全、稳定、免费且开源的特性,成为项目部署的首选操作系统。无论是 Java 项目,还是各类开发、测试、生产环境中的软件安装,Linux 都占据着重要地位。本文将结合我今天所学内容,…...
Spring Boot Actuator使用
说明:本文介绍Spring Boot Actuator的使用,关于Spring Boot Actuator介绍,下面这篇博客写得很好,珠玉在前,我就不多介绍了。 Spring Boot Actuator 简单使用 项目里引入下面这个依赖 <!--Spring Boot Actuator依…...
[css] 黑白主题切换
link动态引入 类名切换 css滤镜 var 类名切换 v-bind css预处理器mixin类名切换 【前端知识分享】CSS主题切换方案...
阿里云专有云网络架构学习
阿里云专有云网络架构 叶脊(spine-leaf)网络和传统三层网络拓扑对比 阿里云网络架构V3拓扑角色介绍推荐设备设备组网举例带外管理网络带外网和带内网对比设备介绍 安全网络设备介绍 参考 后续更新流量分析叶脊(spine-leaf)网络和传…...
【AIGC】冷启动数据与多阶段训练在 DeepSeek 中的作用
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯冷启动数据的作用冷启动数据设计 💯多阶段训练的作用阶段 1:冷启动微调阶段 2:推理导向强化学习(RL࿰…...
在SIP路由中,常见的对接方式
好的,我已将应用场景和案例分为两列。修改后的表格如下: 对接方式描述应用场景案例注册 (REGISTER)用于用户注册,将用户位置(如IP地址)与其用户名进行绑定。用户通过发送REGISTER请求将自己注册到SIP服务器。注册过程…...
GenAI + 电商:从单张图片生成可动态模拟的3D服装
在当今数字化时代,电子商务和虚拟现实技术的结合正在改变人们的购物体验。特别是在服装行业,消费者越来越期待能够通过虚拟试衣来预览衣服的效果,而无需实际穿戴。Dress-1-to-3 技术框架正是为此而生,它利用生成式AI模型(GenAI)和物理模拟技术,将一张普通的穿衣照片转化…...
harmonyOS生命周期详述
harmonyOS的生命周期分为app(应用)的生命周期和页面的生命周期函数两部分 应用的生命周期-app应用 在app.js中写逻辑,具体有哪些生命周期函数呢,请看下图: onCreated()、onShow()、onHide()、onDestroy()这五部分 页面及组件生命周期 着重说下onShow和onHide,分别代表是不是…...
