共享单车(八):数据库

实现后台数据库访问模块的框架,能够实现验证请求并响应(支持数据库操作)。
在这里插入图片描述

数据库设计

class SqlTabel	//负责数据库表的创建
{
public:SqlTabel(std::shared_ptr<MysqlConnection> sqlconn) :sqlconn_(sqlconn) {}bool CreateUserInfo()        //创建用户表{const char* pUserInfoTabel = " \CREATE TABLE IF NOT EXISTS userinfo( \id            int(16)          NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT'用户id', \mobile        varchar(16)      NOT NULL DEFAULT '13000000000' COMMENT'手机号', \username      varchar(128)     NOT NULL DEFAULT '' COMMENT'用户名', \verify        int(4)           NOT NULL DEFAULT 0 COMMENT'验证',  \registertm    timestamp        NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'注册时间', \money         int(4)           NOT NULL DEFAULT 0 COMMENT'余额', \INDEX         mobile_index(mobile)   \)";if (!sqlconn_->Execute(pUserInfoTabel)){LOG_ERROR("create table userinfo table failed. error msg: %s", sqlconn_->GetErrInfo());return false;}return true;}bool CreateBikeTable()        //创建单车表{const char* pBikeInfoTabel = " \CREATE TABLE IF NOT EXISTS bikeInfo( \id            int              NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT'单车id', \devno         int              NOT NULL COMMENT'单车编号', \status        tinyint(1)       NOT NULL DEFAULT 0 COMMENT'单车状态', \trouble       int              NOT NULL DEFAULT 0 COMMENT'损坏类型编号', \tmsg          varchar(256)     NOT NULL DEFAULT '' COMMENT'损坏原因描述', \latitude      double(10, 6)    NOT NULL DEFAULT 0 COMMENT'维度', \longitude     double(10, 6)    NOT NULL DEFAULT 0 COMMENT'经度', \UNIQUE(devno)    \)";if (!sqlconn_->Execute(pBikeInfoTabel)){LOG_ERROR("create table bikeinfo table failed. error msg: %s", sqlconn_->GetErrInfo());return false;}return true;}private:std::shared_ptr<MysqlConnection> sqlconn_;
};

数据库访问

class SqlRecordSet {	//数据库访问接口
public:SqlRecordSet() :m_pRes(NULL){}explicit SqlRecordSet(MYSQL_RES* pRes)// 不能隐式构造{m_pRes = pRes;}MYSQL_RES* MysqlRes(){return m_pRes;}~SqlRecordSet() {if (m_pRes){mysql_free_result(m_pRes);	// 释放一个结果集合使用的内存}}/** 你已经设置了结果集,此时若要再次设置结果集,那么之前的结果集就访问不到了.(那之前的结果集访问不到了,之间的结果集还没来的及释放,就是内存泄漏)* 所以,你要设置结果集的前提是:结果集是空的.* 不是空的,咱们不让他设置*///设置结果集inline void SetResult(MYSQL_RES* pRes){//如果此时已经保存了结果集,那么就应该让程序报错,防止内存泄漏assert(m_pRes == NULL);if (m_pRes){LOG_WARN("the MYSQL_RES has already stored result , maybe will case memory leak\n");}m_pRes = pRes;}//获取结果集inline MYSQL_RES* GetResult(){return m_pRes;}//获取里面的行void FetchRow(MYSQL_ROW& row){row = mysql_fetch_row(m_pRes);	// 检索结果集的下一行}//返回具体行的数量inline i32 GetRowCount(){return m_pRes->row_count;}
private:MYSQL_RES* m_pRes;	// 存放mysql结果集的数据结构
};

协调处理事务

class BusinessProcessor	//负责协调处理事务
{
public:BusinessProcessor(std::shared_ptr<MysqlConnection> conn);bool init();virtual ~BusinessProcessor();private:std::shared_ptr<MysqlConnection> mysqlconn_;	//数据库连接std::shared_ptr<UserEventHandler> ueh_;        //用户事件处理器//...可以增添其它事件处理器
};

数据库操作

class MysqlConnection {
public:MysqlConnection();~MysqlConnection();MYSQL* Mysql(){return mysql_;}//初始化bool Init(const char* szHost, int nPort, const char* szUser, const char* szPasswd, const char* szDb);	//不需要/需要拿到结果bool Execute(const char* szSql);//MYSQL_RES *bool Execute(const char* szSql, SqlRecordSet& recordSet);//将pSrc特殊字符进行转义,一些特殊字符如果不转义,sql查询就会报错int EscapeString(const char* pSrc, int nSrcLen, char* pDest);void Close();//得到错误信息的方法const char* GetErrInfo();//服务断掉了,重连void Reconnect();
private:MYSQL* mysql_;//mysql的句柄,用于操作数据库
};

初始化

bool MysqlConnection::Init(const char* szHost, int nPort, const char* szUser, const char* szPasswd, const char* szDb)
{LOG_INFO("enter Init.\n");//初始化if (mysql_init(mysql_) == NULL) {   //  mysql_init 用来分配或者初始化一个MYSQL对象,用于连接mysql服务端->失败=NULL 成功=!NULLLOG_ERROR("init mysql failed %s , %d", this->GetErrInfo(), errno);return false;}//因为网络等原因,断开后自动重连char cAuto = 1;if (mysql_options(mysql_, MYSQL_OPT_RECONNECT, &cAuto)!=0)  // 用于设置 MySQL 连接的选项->成功返回0{LOG_ERROR("mysql_options MYSQL_OPT_RECONNEC failed.");}//连接//“host”的值必须是主机名或IP地址//“user”参数包含用户的MySQL登录ID//“passwd”参数包含用户的密码//“db”是数据库名称//如果“port”不是0,其值将用作TCP/IP连接的端口号//如果unix_socket不是NULL,该字符串描述了应使用的套接字或命名管道。//client_flag的值通常为0if (mysql_real_connect(mysql_, szHost, szUser, szPasswd, szDb, nPort, NULL, 0) == NULL) // 与运行在主机上的MySQL数据库引擎建立连接{LOG_ERROR("connect mysql failed : %s ", this->GetErrInfo());}return true;}

查询结果

bool MysqlConnection::Execute(const char* szSql)
{if (mysql_real_query(mysql_, szSql, strlen(szSql)) != 0)    // 执行szSql语句->成功=0 失败=-1{if (mysql_errno(mysql_) == CR_SERVER_GONE_ERROR)//断开连接就重连{Reconnect();}return false;}return true;
}bool MysqlConnection::Execute(const char* szSql, SqlRecordSet& recordSet)
{//先进行sql查询,看是否能够执行成功?if (mysql_real_query(mysql_, szSql, strlen(szSql)) != 0){if (mysql_errno(mysql_) == CR_SERVER_GONE_ERROR)    // error code{Reconnect();    // 重连 }return false;}//执行成功了,就将查到的结果设置到结果集中MYSQL_RES* pRes = mysql_store_result(mysql_);if (!pRes) {return NULL;//设置失败,返回空,说明mysql_store_result失败了}recordSet.SetResult(pRes);//将结果放入结果集return false;
}

转义

/*
* pSrc  转义前的字符
* pDest 转义后的字符
*/
int MysqlConnection::EscapeString(const char* pSrc, int nSrcLen, char* pDest)
{if (!mysql_){return 0;}// mysql必须是有效的开放式连接,将“from”中的字符串编码为转义SQL字符串,将结果置于“to”中,并添加1个终结用NULL字节return mysql_real_escape_string(mysql_, pDest, pSrc, nSrcLen);//将源src转义到目标子串dest}

相关知识

1.安装mysql c++库

sudo apt-get install libmysql++-dev
sudo systemctl mysql-server

2.安装mysql

sudo apt-get install mysql-server
sudo apt-get install mysql-client
systemctl status mysql.service #请检是否安装成功

3.进入 MySQL

sudo mysql -u root -p

4.创建数据库

CREATE TABLE `users`(`use` VARCHAR(50) NOT NULL COMMENT 'id',`pwd` VARCHAR(50) NOT NULL COMMENT 'passwd',PRIMARY KEY (`use`)
)ENGINE=INNODB DEFAULT CHARSET=utf8INSERT INTO `users`(`use`,`pwd`) VALUES ('aa' , 'bb'),('cc','dd');

5.常用操作

https://learn.microsoft.com/zh-cn/azure/mysql/single-server/connect-cpp
https://blog.csdn.net/qq_60755751/article/details/136631798

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

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

相关文章

超值分享50个DFM模型格式的素人直播资源,适用于DeepFaceLive的DFM合集

50直播模型&#xff1a;点击下载 作为直播达人&#xff0c;我在网上购买了大量直播用的模型资源&#xff0c;包含男模女模、明星脸、大众脸、网红脸及各种稀缺的路人素人模型。现在&#xff0c;我将这些宝贵的资源整理成合集分享给大家&#xff0c;需要的朋友们可以直接点击下…

电商项目之有趣的支付签名算法

文章目录 1 问题背景2 思路3 代码实现 1 问题背景 在发起支付的时候&#xff0c;一般都需要对发送的请求参数进行加密或者签名&#xff0c;下文简称这个过程为“签名”。行业内比较普遍的签发算法有&#xff1a; &#xff08;1&#xff09;按支付渠道给定的字段排序进行拼接&am…

amis 联动效果触发的几种方式

联动效果实现主要俩种方式: 1.表达式实现联动,基于组件内或数据链的变量变化的联动 比如&#xff1a; "source": "/amis/api/mock2/options/level2?name${name} " (必须是这种字符串拼接形式,在data数据映射中表达式不会触发联动) 所有初始化接口链…

Docker学习(3):镜像使用

当运行容器时&#xff0c;使用的镜像如果在本地中不存在&#xff0c;docker 就会自动从 docker 镜像仓库中下载&#xff0c;默认是从 Docker Hub 公共镜像源下载。 一、列出镜像列表 可以使用 docker images 来列出本地主机上的镜像。 各个选项说明&#xff1a; REPOSITORY&am…

UDP的报文结构和注意事项

UDP协议是在传输层的协议。 UDP无连接&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工。 UDP的报文结构 学习网络协议&#xff0c;最主要的就是报文格式。 对于UDP来说&#xff0c;应用层的数据到达&#xff0c;UDP之后&#xff0c;就会给应用层的数据报前面…

大工作量LUAD代谢重编程模型多组学(J Transl Med)

目录 1&#xff0c;单细胞早期、晚期和转移性 LUAD 的细胞动力学变化 2&#xff0c;细胞代谢重编程介导的LUAD驱动恶性转移的异质性 3&#xff0c;模型构建 S-MMR评分管线构建 4&#xff0c;S-MMR 模型的预后评估 5&#xff0c; 还开发了S-MMR 评分网络工具 6&#xff0c…

从零开始搭建Springboot项目脚手架4:保存操作日志

目的&#xff1a;通过AOP切面&#xff0c;统一记录接口的访问日志 1、加maven依赖 2、 增加日志类RequestLog 3、 配置AOP切面&#xff0c;把请求前的request、返回的response一起记录 package com.template.common.config;import cn.hutool.core.util.ArrayUtil; import cn.hu…

面试八股之JVM篇3.6——垃圾回收——强引用、弱引用、虚引用、软引用

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

【机器学习系列】使用高斯贝叶斯模型进行数据分类的完整流程

目录 一、导入数据 二、选择特征 三、十折交叉验证 四、划分训练集和测试集 五、训练高斯贝叶斯模型 六、预测测试集 七、查看训练集和测试集上的分数 八、查看混合矩阵 九、输出评估指标 一、导入数据 # 根据商户数据预测其是否续约案例 import pandas #读取数据到 da…

YOLOv10 论文学习

论文链接&#xff1a;https://arxiv.org/pdf/2405.14458 代码链接&#xff1a;https://github.com/THU-MIG/yolov10 解决了什么问题&#xff1f; 实时目标检测是计算机视觉领域的研究焦点&#xff0c;目的是以较低的延迟准确地预测图像中各物体的类别和坐标。它广泛应用于自动…

结构体(位段)内存分配

结构体由多个数据类型的成员组成。那编译器分配的内存是不是所有成员的字节数总和呢&#xff1f; 首先&#xff0c;stu的内存大小并不为29个字节&#xff0c;即证明结构体内存不是所有成员的字节数和。   其次&#xff0c;stu成员中sex的内存位置不在21&#xff0c;即可推测…

CS 下载安装详解

目录 CS简介&#xff1a; CS下载地址&#xff1a; CS的安装&#xff1a; CS简介&#xff1a; CS为目前渗透中常用的一款工具&#xff0c;它的强大在于控制windows木马&#xff0c;CS主要控制windows木马。 CS下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/…

【Linux】-Zookeeper安装部署[17]

简介 apache ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能包括&#xff1a;配置维护、域名服务、分布式同步、组服务等。 除了为Hadoop和H…

【设计模式】JAVA Design Patterns——Bridge(桥接模式)

&#x1f50d;目的 将抽象与其实现分离&#xff0c;以便二者可以独立变化。 &#x1f50d;解释 真实世界例子 考虑一下你拥有一种具有不同附魔的武器&#xff0c;并且应该允许将具有不同附魔的不同武器混合使用。 你会怎么做&#xff1f; 为每个附魔创建每种武器的多个副本&…

【论文阅读】 YOLOv10: Real-Time End-to-End Object Detection

文章目录 AbstractIntroductionRelated WorkMethodologyConsistent Dual Assignments for NMS-free Training &#xff08;无NMS训练的一致性双重任务分配&#xff09;Holistic Efficiency-Accuracy Driven Model Design &#xff08;效率-精度驱动的整体模型设计&#xff09; …

huggingface 笔记:查看GPU占用情况

0 准备部分 0.1 创建虚拟数据 import numpy as npfrom datasets import Datasetseq_len, dataset_size 512, 512 dummy_data {"input_ids": np.random.randint(100, 30000, (dataset_size, seq_len)),"labels": np.random.randint(0, 1, (dataset_size…

C++与Android处理16进制大端/小端数据实例(二百七十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

民国漫画杂志《时代漫画》第14期.PDF

时代漫画14.PDF: https://url03.ctfile.com/f/1779803-1247458399-6732ac?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络&#xff01;

OWASP top10--SQL注入(一)

SQL注入式攻击技术&#xff0c;一般针对基于Web平台的应用程序.造成SQL注入攻击漏洞的原因&#xff0c;是由于程序员在编写Web程序时&#xff0c;没有对浏览器端提交的参数进行严格的过滤和判断。用户可以修改构造参数&#xff0c;提交SQL查询语句&#xff0c;并传递至服务器端…

基本IO接口

引入 基本输入接口 示例1 示例2&#xff1a;有数据保持能力的外设 #RD端由in指令控制&#xff1a;将数据由端口传输到CPU内存中 #CS244信号由译码电路实现 示例3&#xff1a; a)图中由于输出端口6有连接到端口1&#xff0c;当开关与端点1闭合时期间&#xff0c;仍能维持3端口…