封装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 <windows.h>
#include <my_global.h>
#include <mysql.h>
#include <iostream> 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过的数据库。
封装MySQL C API 基本操作的更多相关文章
- mysql数据库的基本操作
mysql数据库的基本操作dos命令启动mysql服务:net start mysql启动数据库: mysql -uroot -p查看所有的数据库:show databases:新建数据库:creat ...
- PHP数据库操作:从MySQL原生API到PDO
本文将举详细例子向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对象.PDO操作MySQL数据库的. 为了后面的测试,先建立数据库表test.包含表名user,s ...
- Java封装自己的Api
转自:http://www.2cto.com/kf/201404/291555.html 随着学习的深入,我们都想封装自己的Api,但对于新手这并不是一件简单容易的事! 我要达到的效果:自己封装一些方 ...
- php 封装mysql 数据库操作类
<?phpheader('content-type:text/html;charset=utf-8');//封装mysql 连接数据库php_mysql//封装mysql 连接数据库ph ...
- c++使用mysql的api连接相关问题
记录一下自己使用中的相关问题,方便有相同问题的同学解决. 关于在VS中的各种配置.看这里.只是须要注意一下,我如今用的mysql版本号是5.6的,已经没有[MySQL Server \lib\opt] ...
- mysql C API 字符串玩转备份调优
- The MySQL C API 编程实例
在网上找了一些MYSQL C API编程的文章,看了后认为还是写的不够充分,依据自己经验写了这篇<The MySQL C API 编程实例>,希望对须要调用到MYSQL的C的API的朋友有 ...
- MySQL C API概述
以下列表总结了C API中可用的功能.有关更多详细信息,请参见 第27.8.7节“C API函数描述”中的说明. my_init():在线程安全程序中初始化全局变量和线程处理程序 mysql_affe ...
- python 以单例模式封装logging相关api实现日志打印类
python 以单例模式封装logging相关api实现日志打印类 by:授客QQ:1033553122 测试环境: Python版本:Python 2.7 实现功能: 支持自由配置,如下lo ...
随机推荐
- Python 实现0-1背包
代码: import numpy as np c=10 #背包容量 w=[2,2,6,5,4] #物品重量 v=[5,3,5,4,6] #物品价值 flag =[0,0,0,0,0] m=np.zer ...
- day 54 Django基础四之模板系统
Django基础四之模板系统 本节目录 一 语法 二 变量 三 过滤器 四 标签Tags 五 模板继承 六 组件 七 自定义标签和过滤器 八 静态文件相关 一 语法 模板渲染的官方文档 关于模 ...
- Java中关于注释、标识符、变量、常量、数据类型、类型转换、转移字符以及数值型的表现形式的详解
Java文件的注意事项 在同一个Java文件中,可以定义多个类,但是被public修饰的类只能够有一个,并且此类名要与文件名一致. 在同一个类中,可以定义多个方法,但是名字叫做main的方法只能有一个 ...
- telnet- Linux必学的60个命令
1.作用 telnet表示开启终端机阶段作业,并登入远端主机.telnet是一个Linux命令,同时也是一个协议(远程登陆协议). 2.格式 telnet [-8acdEfFKLrx][-b][-e] ...
- uoj60 怎样提高智商
题意:你需要构造n个四项选择题.格式为:问在前i个问题中选了几个hi字母? 输出有最多正确答案的构造方案. 标程: #include<cstdio> using namespace std ...
- 边缘节点服务ENS重磅升级 阿里云首次定义“边缘云计算”概念层层深入
随着5G.物联网时代的到来以及云计算应用的逐渐增加,传统集中式的云计算技术已经无法满足终端侧“大连接,低时延,大带宽”的需求.结合边缘计算的概念,云计算将必然发展到下一个技术阶段,也就是将云计算的能力 ...
- Python-面向对象之封装与多态
目录 组合 什么是组合 使用组合的目的 如何使用组合 封装 什么是封装 为什么要封装 如何封装 访问限制机制 什么是访问限制机制 访问限制机制的目的 如何使用访问限制 property 什么是prop ...
- 19-11-14-Finally
如果这是世界末日的前一晚, 这是我的回答. #include <bits/stdc++.h> using namespace std; int main(){ cout<<&q ...
- Java笔记 - 输入输出流
java.io包中定义了各式各样的"流(stream)" 类型(类或抽象类),通过标准的方法实现对于数据的输入/输出操作. 一.流类型分类 以从不同的角度对其进行分类:按数据流的方 ...
- 由VMnet引起的browser-sync故障解决方案
(2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2016年7月11日) 今天晚上,前端组的小伙伴问我说能不能帮忙看看他的电脑为什么在安装了browser-sync插件以后, ...