mysql c api 封装_封装MySQL C API 基本操作

根据我的以前的文章 http://blog.csdn.net/skyhuangdan/article/details/21099929 链接数据库成功后进行封装。

我封装类使用的是VS2005下的win32控制台应用程序编写,预编译头文件了的。

所以要在 stdafx.h 里面加入 :

#include "CMySQL.h"

现在代码奉上:

main函数代码:mysql2.cpp

// mysql2.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

int main()

{

CMySQL mysql;

int re = mysql.Connect("localhost", "root", "123456");

mysql.ReConnect();

char buffer[1024] = {0};

while(1)

{

memset(buffer, 0, 1024);

printf("please input cmd:\n");

if( strcmp( "quit", gets(buffer)) != 0 )

{

if( (char) '1'== buffer[0] ){

mysql.SelectQuery(buffer+1);

}else{

mysql.ModifyQuery(buffer+1);

printf("Modify\n");

}

}else

break;

}

getchar();

}

CMySQL.h

#pragma once

#include

#include

#include

#include

using namespace std;

/*

#define ERRMSG1(fmt,...) ; sprintf(m_szErrMsg, fmt, __VA_ARGS__);

#define ERRMSG2(fmt,args...) ; sprintf(m_szErrMsg, "[%s 第 %d 行 ]; "fmt"\r\n" , __FILE__, __LINE__, ##args);

*/

class CMySQL

{

public:

CMySQL(void);

public:

~CMySQL(void);

public:

bool m_bConnected; //数据库连接了吗? true--已经连接; false--还没有连接

char m_szErrMsg[1024]; //函数出错后, 错误信息放在此处

int m_iFields; //字段个数

MYSQL m_connection; //连接

MYSQL_RES* m_result; //结果集指针

MYSQL_ROW m_row; //一行, typedef char **MYSQL_ROW;

private:

string m_sDbIp; //数据库服务器IP

string m_sUser; //用户名

string m_sPassword; //口令

public:

int Connect(const char* szDbIp, const char* szUser, const char* szPassword);

//关闭连接,无论之前是否已经连接,使用这个函数都不会有问题

void CloseConnect();

//判断是否连接

bool IsConnected();

//连接标志

void SetConnected(bool bTrueFalse );

//重新连接

int ReConnect();

//用于执行查询命令,并且把查询到的结果集保存到m_result结果集里面

//!!此函数调用SelectPrint()函数!!

int SelectQuery(const char* szSQL);

//只是执行SQL命令

int ModifyQuery(const char* szSQL);

//返回错误信息

const char* GetErrMsg();

//保存连接参数

void SaveParam(const char* szDbIp, const char* szUser, const char* szPassword);

//释放上次的结果

void FreePreResult();

//显示结果?

void PrintSelect();

};

CMySQL.cpp:

#include "StdAfx.h"

#include "CMySQL.h"

CMySQL::CMySQL(void)

{

SetConnected(false);

//把结果集置空

m_result = NULL;

//初始化连接

mysql_init(&m_connection);

}

CMySQL::~CMySQL(void)

{

//释放上一次的结果集

FreePreResult();

//关闭数据库连接

CloseConnect();

}

int CMySQL::Connect(const char* szDbIp, const char* szUser, const char* szPassword)

{

SaveParam(szDbIp, szUser, szPassword);

//先判断释放已连接,防止重复连接

if (IsConnected())

return 0;

//连接数据库

if (mysql_real_connect( &m_connection, szDbIp, szUser, szPassword, NULL, 0,NULL, 0) == NULL)

{

sprintf(m_szErrMsg,"%s" ,mysql_error(&m_connection));

return -1;

}

printf("[mysql] conn to %s [user:%s] succ!\r\n", szDbIp, szUser);

//设置连接标志为 true

SetConnected(true);

return 0;

}

void CMySQL::CloseConnect()

{

//不论m_connection曾经是否连接过, 这样关闭都不会有问题

mysql_close(&m_connection);

SetConnected(false);

}

bool CMySQL::IsConnected() {

return m_bConnected;

}

void CMySQL::SetConnected(bool bTrueFalse)

{

m_bConnected = bTrueFalse;

}

void CMySQL::FreePreResult()

{

if (m_result != NULL)

{

mysql_free_result(m_result);

m_result = NULL;

}

}

int CMySQL::SelectQuery(const char* szSQL)

{

//如果查询串是空指针,则返回

if (szSQL == NULL) {

sprintf(m_szErrMsg,"%s", "szSQL==NULL");

return -1;

}

//如果还没有连接,则返回

if (!IsConnected()) {

sprintf(m_szErrMsg,"%s" , "还没有建立连接");

return -2;

}

try //这些语句与连接有关,出异常时就重连

{

//查询

if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0)

{

sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));

printf("%s", mysql_error(&m_connection));

printf("ReConnect() is called, select111 !!!***@\r\n");

int nRet = ReConnect();

if (nRet != 0)

return -3;

//

if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0)

return -33;

//

}

//释放上一次的结果集

FreePreResult();

//取结果集

m_result = mysql_store_result(&m_connection);

if (m_result == NULL) {

sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));

return -4;

}

} catch (...) {

printf("ReConnect() is called, select !!!***@!@\r\n");

ReConnect();

return -5;

}

//取字段的个数

m_iFields = mysql_num_fields(m_result);

//查询完过后进行打印出来

this->PrintSelect();

return 0;

}

int CMySQL::ReConnect() {

CloseConnect();

//连接数据库

SetConnected(false);

//把结果集置空

m_result = NULL;

//初始化连接

mysql_init(&m_connection);

if (mysql_real_connect(&m_connection, m_sDbIp.c_str(), m_sUser.c_str(),m_sPassword.c_str(), NULL, 0, NULL, 0) == NULL)

{

sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));

return -1;

}

//设置连接标志为 true

SetConnected(true);

return 0;

}

const char* CMySQL::GetErrMsg() {

return m_szErrMsg;

}

void CMySQL::SaveParam(const char* szDbIp, const char* szUser,

const char* szPassword) {

m_sDbIp = szDbIp; //数据库服务器IP

m_sUser = szUser; //用户名

m_sPassword = szPassword; //口令

}

void CMySQL::PrintSelect()

{

printf("\n------------------------------------------------\n");

int num_fields = mysql_num_fields(m_result);

while ( m_row = mysql_fetch_row( m_result) )

{

for( int i = 0; i < num_fields; i++ )

{

if(m_row[i])

printf("%s ", m_row[i]);

else

printf("NULL");

}

printf("\n");

}

printf("\n------------------------------------------------\n");

}

int CMySQL::ModifyQuery(const char* szSQL) {

//如果查询串是空指针,则返回

if (szSQL == NULL) {

sprintf(m_szErrMsg,"%s", "szSQL==NULL");

return -1;

}

//如果还没有连接,则返回

if (!IsConnected()) {

sprintf(m_szErrMsg,"%s", "还没有建立连接");

return -2;

}

try //这些语句与连接有关,出异常时就重连

{

//查询, 实际上开始真正地修改数据库

if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0) {

sprintf(m_szErrMsg,"%s", mysql_error(&m_connection));

return -3;

}

} catch (...) {

printf("ReConnect() is called ,modify!!!***\r\n");

ReConnect();

return -5;

}

return 0;

}

注:

对于输入的MySQL命令错误的情况下,程序会连接一遍,在程序关闭过后用于连接的关键字【MYSQL m_connection; 】必须要初始化,否则程序会出错。

还有,重连过后,必须重新USE XXXXX; 因为重新连接那里并没有自动连接你之前USE过的数据库。

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

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

相关文章

android中怎么保存checkbox中的checked属性_Vue 精粹:v-model指令在组件中怎么玩

最近在写组件的时候&#xff0c;遇到了 v-model 的使用问题&#xff0c;在 Vue 官方文档中&#xff0c;有两小端内容是关于 v-model 指令在组件中的使用,查阅文档后&#xff0c;依然不得要领&#xff0c;最后几番折腾&#xff0c;理论结合实践&#xff0c;终于领悟其精髓&#…

xcode 自动化出包

iOS提高效率之Xcodebuild自动打包总结 - 简书 使用xcodebuild命令进行自动化打包 - 简书 Add a profile to the provisioningProfiles dictionary in your Export Options property list. | 亂馬客 - Re:從零開始的軟體開發生活

linux location root访问文件夹404_如何使网站支持https访问?nginx配置https证书

购买SSL证书要想使用https访问你的网址&#xff0c;首先得拥有颁发的SSL证书。我使用的是免费版&#xff0c;有效期为一年&#xff0c;过期后再重新申请。申请SSL证书购买后&#xff0c;可在搜索框输入证书关键字进入到控制台。点击证书申请&#xff0c;按照提示填写完相关信息…

c++头文件能否包含函数实现?

头文件即.h文件一般是用来写函数或者类的定义的&#xff0c;而函数的实现一般在cpp文件中完成&#xff0e;但是我也看到过一些文件就在头文件中同时定义函数和实现&#xff0e;打个比方我现在有个头文件名叫header.h,内容如下 #include <iostream>void printInt(int numb…

mysql rank函数_Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

排名函数是Sql Server2005新增的功能&#xff0c;下面简单介绍一下他们各自的用法和区别。我们新建一张Order表并添加一些初始数据方便我们查看效果。表结构和初始数据Sql附上表结构和初始数据图&#xff1a;一、ROW_NUMBERrow_number的用途的非常广泛&#xff0c;排序最好用他…

git2.29.2.2怎么安装_MySQL5.5怎么安装

安装MySQL5.5的步骤&#xff1a;1、 官网下载mysql5.5下载地址&#xff1a;http://dev.mysql.com/downloads/mysql/5.5.html#downloads2、 安装mysql5.5注意&#xff0c;安装之前&#xff0c;请关闭杀毒软件。1)、 打开下载的mysql-5.5.53-winx64.msi2) 、点击下一步3)、 选中复…

h、cpp和hpp头文件之间使用区别

hpp&#xff0c;其实质就是将.cpp的实现代码混入.h头文件当中&#xff0c;定义与实现都包含在同一文件&#xff0c;则该类的调用者只需要include该hpp文件即可&#xff0c;无需再将cpp加入到project中进行编译。而实现代码将直接编译到调用者的obj文件中&#xff0c;不再生成单…

未声明spire。它可能因保护级别而不可访问_信息系统安全:访问控制技术概述...

1.访问控制基本概念身份认证技术解决了识别“用户是谁”的问题&#xff0c;那么认证通过的用户是不是可以无条件地使用所有资源呢&#xff1f;答案是否定的。访问控制(Access Control)技术就是用来管理用户对系统资源的访问。访问控制是国际标准ISO7498-2中的五项安全服务之一&…

c++反汇编与逆向分析技术揭秘_C++反汇编与逆向分析技术揭秘

一、单类继承在父类中声明为私有的成员&#xff0c;子类对象无法直接访问&#xff0c;但是在子类对象的内存结构中&#xff0c;父类私有的成员数据依然存在。C语法规定的访问限制仅限于编译层面&#xff0c;在编译过程中进行语法检查&#xff0c;因此访问控制不会影响对象的内存…

std::atomic原子操作

第十一节std::atomic原子操作_HITXJ的博客-CSDN博客_std::atomic用法

mysql 列级权限授予用户_mysql 用户及权限管理 小结

MySQL 默认有个root用户&#xff0c;但是这个用户权限太大&#xff0c;一般只在管理数据库时候才用。如果在项目中要连接 MySQL 数据库&#xff0c;则建议新建一个权限较小的用户来连接。在 MySQL 命令行模式下输入如下命令可以为 MySQL 创建一个新用户&#xff1a;新用户创建完…

python if name main 的作用_Python中if __name__ == __main__: 的作用

在很多python脚本中在最后的部分会执行一个判断语句if __name__ "__main__:"&#xff0c;之后还可能会有一些执行语句。那添加这个判断的目的何在&#xff1f; 在python编译器读取源文件的时候会执行它找到的所有代码&#xff0c;而在执行之前会根据当前运行的模块是…

php与mysql列表_PHP+Mysql+jQuery实现的查询和列表框选择

本篇文章主要介绍PHPMysqljQuery实现的查询和列表框选择&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。本文讲解如何通过ajax查询mysql数据&#xff0c;并将返回的数据显示在待选列表中&#xff0c;再通过选择最终将选项加入到已选区&#xff0c;可以用在许多…

range函数python2和3区别_range函数python2和3区别

range函数是一个用来创建算数级数序列的通用函数&#xff0c;返回一个[start, start step, start 2 * step, ...]结构的整数序列&#xff1b;py2中的range()函数用法&#xff1a;&#xff08;推荐学习&#xff1a;Python视频教程&#xff09; range()返回的是一个列表>>&…

Unity SRP自定义渲染管线 -- 2.Custom Shaders

本章将接着上一篇文章&#xff0c;在初步实现一个渲染管线后来创建自定义的shader。上一篇文章的链接 https://blog.csdn.net/yinfourever/article/details/90516602。在本章中&#xff0c;将完成以下内容&#xff1a; 写一个HLSL Shader定义constant buffer&#xff08;常量缓…

tcp 三次握手与四次挥手_TCP三次握手与四次挥手详解

TCP报文结构源端口和目的端口&#xff1a;各占2个字节&#xff0c;分别写入源端口号和目的端口号。序号&#xff1a;占4个字节。序号使用mod运算。TCP是面向字节流的&#xff0c;在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。故该字段也叫做“报文段序号”。确认序…

网关和路由器的区别_5G工业路由器与5G DTU的区别介绍详解

5G工业路由器和5G DTU都是实现无线网络数据传输功能&#xff0c;而两者间的区别主要从使用方法、外观接口以及应用环境等方面区分&#xff0c;今天给大家介绍5G工业路由器和5G DTU的一些不同点。使用方法的不同:5G工业路由器&#xff1a;5G路由器可对以太网、现场总线通信协议进…

7628刷breed_自制各类路由原厂直刷Breed的文件,无需修改mac无需重刷无线

本帖最后由 showme99 于 2017-3-25 16:35 编辑在原厂页面直接选择相应的刷机文件刷机&#xff0c;文件很小256K&#xff0c;大约十秒左右就自动进入Breed后直接刷入dd-wrt,opentwrt,gargoyle等固件即可。无需在Breed里设置MAC地址&#xff0c;也无需刷入ART无线文件&#xff0c…

c语言获取系统剩余内存_C语言编程中的“堆”和“栈”七大不同之处

更多精彩&#xff0c;请点击上方蓝字关注我们&#xff01;对于编程初学者来说会接触到一些难以理解的名称&#xff0c;比如堆(heap)、栈(stack)、堆栈(stack)等。初学开发过程中往往让人混淆不清。今天我们来谈谈堆和栈的具体区别&#xff0c;来帮助初学者理清思路。堆和栈的区…

sql between包括两端吗_SQL大全

作者&#xff1a;静默虚空排版&#xff1a;MarkerHub原文&#xff1a;https://juejin.im/post/5c7e524af265da2d914db18f本文针对关系型数据库的一般语法。限于篇幅&#xff0c;本文侧重说明用法&#xff0c;不会展开讲解特性、原理。一、基本概念数据库术语数据库(database) -…