MySql数据库是常用的免费数据库,据说比商业的也不弱多少。数据量大时不可能只用脚本。还是有使用mysql的必要的。基本教程
第一步:下载、安装、连接。
mysql的下载、安装:http://jingyan.baidu.com/article/1876c852b15485890b1376f2.html
本文用的是mysql-5.6.24-win32 绿色版。
常用的用cmd测试的命令:
cd F:\mysql-5.6.24-win32.1432006610\mysql-5.6.24-win32\bin
启动:net start mysql
输入:mysql -uroot -p
password: root
第二步。ok。假设你已经成功的启动了mysql,下面就是c++与mysql的连接了。
首先配置项目。
附加包含目录:F:\mysql-5.6.24-win32.1432006610\mysql-5.6.24-win32\include(对应你自己的include)
附加库目录:F:\mysql-5.6.24-win32.1432006610\mysql-5.6.24-win32\lib(对应你自己的lib)
附加依赖项:libmysql.lib;WS2_32.LIB
WS2_32.LIB 加到自己的lib文件夹中
第三步。加代码。源码
.h
#pragma once
#include "mysql.h"
#include <Afxmt.h>
#include <afxsock.h>
#define DEFAULT_FIELD 32 //你所要操作的库中,数据表的最大的字段数。假如student表有5个字段,
//分别是name,old,sex,profession,class,而teacher表有10个字段,则
//此值应添10。最好设置为最大字段数,设置太大会占用非常大的内存。
#define DEFAULT_FIELD_SIZE 32 //每个字段名称的最大字节数。如:name为4个字节,profession为10个字节
//此处应该添10。注意:一个汉字等于2个字节,不建议使用汉字作为字段名。
//同样,此值也不应该设置过大,否则也会占用非常大的内存。
class OwnSql
{
public:
OwnSql(void);
~OwnSql(void);
//连接OwnSql服务器,
BOOL Connect(char * host,char * name,char *pwd,char * db,unsigned port);
//执行非查询语句,返回成功或失败
BOOL ExecuteNoQuery(char ** sqlArray,int count);
//执行查询语句,返回查询到的行数,处理完结果后,要调用FreeResult释放结果
//如果不调用FreeResult,则在下次查询时自动释放上次的结果集
unsigned ExecuteQuery(char * sql);
//释放查询的结果集
void FreeResult();
//改变用户,使用却省db,如果db为空,则不使用
BOOL ChangeUser(char * name,char *pwd,char *db);
//以当前用户的身份,连接其他数据库
BOOL SelectDB(char * db);
//关闭连接
void Close();
//执行带参数的非SELECT SQL语句
//以下四个函数无法在4.1以下的版本中使用
BOOL ExecutePrepare(char * sql);
BOOL BindParam(MYSQL_BIND * bind);
unsigned Execute();
BOOL ClosePrepare();
//获得指定行和指定列的整形值
//行列都从0开始编号
// row :行号
// fd_name :列名称
// fd_num :列字段号
// 注意 :Get**Value系列函数的参数要确保正确,否则不保证返回值将正确
int GetIntValue(int row, char * fd_name);
int GetIntValue(int row, int fd_num);
//获得符点型值
//从0开始编号
float GetFloatValue(int row,char * fd_name);
float GetFloatValue(int row,int fd_num);
//获得高精度符点型值
//从0开始编号
double GetDoubleValue(int row,char * fd_name);
double GetDoubleValue(int row,int fd_num);
//获得布尔型值
//从0开始编号
BOOL GetBoolValue(int row,char * fd_name);
BOOL GetBoolValue(int row,int fd_num);
//获得字符串值,返回字符串长度
//从0开始编号
char * GetStringValue(int row,char * fd_name, unsigned * len);
char * GetStringValue(int row,int fd_num,unsigned * len);
//获得日期时间型数据,以字符串形式表示
//从0开始编号
//格式如下:0000-00-00 00:00:00
char * GetDataTimeValue(int row,char * fd_name);
char * GetDataTimeValue(int row, int fd_num);
//获得二进制数据的缓冲区
//从0开始编号,当传递给pBuf==NULL时,获得缓冲区长度
int GetBinaryValue(int row,char * fd_name,char * pBuf);
int GetBinaryValue(int row,int fd_num,char * pBuf);
private:
//MySql的连接句柄
MYSQL myData;
//MySql预处理句柄
MYSQL_STMT *myStmt;
//MySql的结果集
MYSQL_RES *result;
//存储查询结果集的HashTable
CMapWordToPtr res;
char m_pwd[32];
public:
char m_host[32],m_name[32];
unsigned m_port;
};
.cpp
#include "StdAfx.h"
#include "OwnSql.h"
//一个字段结构
typedef struct _FIELDS
{
char field_name[DEFAULT_FIELD_SIZE];//字段名
void * filed_value; //字段值的指针
unsigned value_len; //字段的长度,只适用于字符串类型
}FIELDS,*PFIELDS;
//一行数据的结构数组
typedef struct _ROWS{
FIELDS fields[DEFAULT_FIELD]; //字段,根据不同的应用程序可以修改此值
int cnt; //多少个字段,指示field中元素的有效个数
}ROWS,*PROWS;
OwnSql::OwnSql(void)
{
result=NULL;
memset(m_host,0,32);
memset(m_name,0,32);
memset(m_pwd,0,32);
m_port=0;
mysql_init(&myData);
//设置连接超时
unsigned timeout=5*60;
mysql_options(&myData, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout);
//启动再连接
my_bool reconnect=TRUE;
mysql_options(&myData, MYSQL_OPT_RECONNECT, (char *)&reconnect);
//初始化HashTable大小为100
res.InitHashTable(100);
}
OwnSql::~OwnSql(void)
{
Close();
}
//连接OwnSql服务器
BOOL OwnSql::Connect(char * host,char * name,char *pwd,char * db,unsigned port)
{
BOOL bRet=TRUE;
strcpy(m_host,host);
strcpy(m_name,name);
strcpy(m_pwd,pwd);
m_port=port;
do
{
//连接服务器
if(mysql_real_connect(&myData,host,name,pwd,db,port,NULL,0)==NULL)
{
bRet=FALSE;
break;
}
//设置连接字符集,默认为GBK
if(mysql_set_character_set(&myData, "GBK"))
{
bRet=FALSE;
//如果设置字符集不成功,则关闭连接
Close();
break;
}
//设置允许多语句支持
mysql_set_server_option(&myData, MYSQL_OPTION_MULTI_STATEMENTS_ON);
}while(0);
return bRet;
}
//执行非查询语句
BOOL OwnSql::ExecuteNoQuery(char ** sqlArray,int count)
{
BOOL uRet=TRUE;
//撤消自动提交模式
mysql_autocommit(&myData, 0);
for(int i=0;i<count;i++)
{
mysql_query(&myData,sqlArray[i]);
//查询受影响的行数
//uRet=uRet+(unsigned)mysql_affected_rows(&myData);
}
//如果没有成功
if(mysql_commit(&myData))
{
//回滚事务
mysql_rollback(&myData);
uRet=FALSE;
}
//恢复自动提交模式
mysql_autocommit(&myData, 0);
return uRet;
}
//执行查询语句
unsigned OwnSql::ExecuteQuery(char * sql)
{
unsigned uLine=0,uField=0;
PROWS rows;
MYSQL_ROW row;
MYSQL_FIELD *pField;
//释放前一次的结果集
FreeResult();
//查询
mysql_query(&myData,sql);
//存储结果集
result=mysql_store_result(&myData);
//如果结果集为空,则返回0
if(result==NULL)return 0;
//获得行数
uLine=(unsigned)mysql_num_rows(result);
//获得字段数
uField=(unsigned)mysql_num_fields(result);
//填充结果集
for(int i=0;i<(int)uLine;i++)
{
//为存储一行数据分配内存
rows=(PROWS)malloc(sizeof(ROWS));
//一行有多少个字段
rows->cnt=uField;
//获得一行数据
row=mysql_fetch_row(result);
for(int j=0;j<(int)uField;j++)
{
//获得该列的相关信息
pField=mysql_fetch_field_direct(result, j);
//列名称
strcpy(rows->fields[j].field_name,pField->name);
//列值
rows->fields[j].filed_value=row[j];
//列宽度
rows->fields[j].value_len=pField->max_length;
}
//将一行数据存储到HashTable中
res.SetAt(i,(void *)rows);
}
//返回行数
return uLine;
}
//释放查询的结果集
void OwnSql::FreeResult()
{
int len=0;
PROWS rows=NULL;
len=res.GetCount();
//释放结果集的内存
for(int i=0;i<len;i++)
{
rows=(PROWS)res[i];
if(rows!=NULL)
{
free(rows);
rows=NULL;
}
}
//清空HashTable
res.RemoveAll();
//释放result
if(result!=NULL)
{
mysql_free_result(result);
}
result=NULL;
}
//执行带参数的SQL语句函数
BOOL OwnSql::ExecutePrepare(char * sql)
{
BOOL bRet=TRUE;
do
{
//初始化句柄
myStmt=mysql_stmt_init(&myData);
if (!myStmt)
{
bRet=FALSE;
break;
}
//准备SQL
if (mysql_stmt_prepare(myStmt, sql, strlen(sql)))
{
bRet=FALSE;
break;
}
}while(0);
return bRet;
}
BOOL OwnSql::BindParam(MYSQL_BIND * bind)
{
BOOL bRet=TRUE;
if (mysql_stmt_bind_param(myStmt, bind))
{
bRet=FALSE;
}
return bRet;
}
unsigned OwnSql::Execute()
{
unsigned uRet=0;
do
{
if (mysql_stmt_execute(myStmt))
{
uRet=0;
break;
}
//获得受影响的行数
uRet=(unsigned)mysql_stmt_affected_rows(myStmt);
}while(0);
return uRet;
}
BOOL OwnSql::ClosePrepare()
{
BOOL bRet=TRUE;
//关闭句柄
if (mysql_stmt_close(myStmt))
{
bRet=FALSE;
}
return bRet;
}
//改变用户
BOOL OwnSql::ChangeUser(char * name,char *pwd,char *db)
{
BOOL bRet=TRUE;
//如果失败,返回FALSE
if(mysql_change_user(&myData, name, pwd, db) )
{
bRet=FALSE;
}
return bRet;
}
//选择数据库
BOOL OwnSql::SelectDB(char * db)
{
BOOL bRet=TRUE;
if(mysql_select_db(&myData, db))
{
bRet=FALSE;
}
return bRet;
}
//关闭
void OwnSql::Close()
{
//清空结果集
FreeResult();
//关闭连接
mysql_close(&myData);
}
//获取查询的值
int OwnSql::GetIntValue(int row, char * fd_name)
{
PROWS rows=NULL;
int len=0;
int iRet=0;
char * tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
//获得数据的字符串表示
tmp=(char *)rows->fields[i].filed_value;
//转换成数字
iRet=atoi(tmp);
break;
}
}
return iRet;
}
int OwnSql::GetIntValue(int row, int fd_num)
{
PROWS rows=NULL;
int len=0,iRet=0;
char * tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//获得数字的字符串表示
tmp=(char *)rows->fields[fd_num].filed_value;
//转换成数字
iRet=atoi(tmp);
return iRet;
}
//获得符点型值
float OwnSql::GetFloatValue(int row,char * fd_name)
{
PROWS rows=NULL;
int len=0;
char * tmp=NULL;
float iRet=0.0;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
tmp=(char *)rows->fields[i].filed_value;
iRet=(float)atof(tmp);
break;
}
}
return iRet;
}
float OwnSql::GetFloatValue(int row,int fd_num)
{
PROWS rows=NULL;
int len=0;
float iRet=0.0;
char * tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
tmp=(char *)rows->fields[fd_num].filed_value;
iRet=(float)atof(tmp);
return iRet;
}
//获得高精度符点型值
double OwnSql::GetDoubleValue(int row,char * fd_name)
{
PROWS rows=NULL;
int len=0;
char * tmp=NULL;
double iRet=0.0;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
tmp=(char *)rows->fields[i].filed_value;
iRet=atof(tmp);
break;
}
}
return iRet;
}
double OwnSql::GetDoubleValue(int row,int fd_num)
{
PROWS rows=NULL;
int len=0;
char * tmp=NULL;
double iRet=0.0;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
tmp=(char *)rows->fields[fd_num].filed_value;
iRet=atof(tmp);
return iRet;
}
//获得布尔型值
BOOL OwnSql::GetBoolValue(int row,char * fd_name)
{
PROWS rows=NULL;
int len=0;
char * tmp=NULL;
BOOL iRet=0;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
tmp=(char *)rows->fields[i].filed_value;
iRet=(BOOL)atoi(tmp);
break;
}
}
return iRet;
}
BOOL OwnSql::GetBoolValue(int row,int fd_num)
{
PROWS rows=NULL;
int len=0;
BOOL iRet=0;
char * tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
tmp=(char *)rows->fields[fd_num].filed_value;
iRet=(BOOL)atoi(tmp);
return iRet;
}
char * OwnSql::GetStringValue(int row,char * fd_name,unsigned * length)
{
PROWS rows=NULL;
int len=0;
char *p_Tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
*length=(unsigned)(rows->fields[i].value_len);
p_Tmp=(char *)(rows->fields[i].filed_value);
break;
}
}
return p_Tmp;
}
char * OwnSql::GetStringValue(int row,int fd_num, unsigned * length)
{
PROWS rows=NULL;
int len=0;
char * p_Tmp=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//获得列长度
*length=(unsigned)rows->fields[fd_num].value_len;
//直接返回此列的值
p_Tmp=(char *)(rows->fields[fd_num].filed_value);
return p_Tmp;
}
//获得日期时间型数据
char * OwnSql::GetDataTimeValue(int row,char * fd_name)
{
PROWS rows=NULL;
int len=0;
char * pTime=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return NULL;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
pTime=(char *)(rows->fields[i].filed_value);
break;
}
}
return pTime;
}
char * OwnSql::GetDataTimeValue(int row, int fd_num)
{
PROWS rows=NULL;
int len=0;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return NULL;
rows=(PROWS)res[row];
//直接返回此列的值
return (char *)(rows->fields[fd_num].filed_value);
}
//获得二进制数据的缓冲区
int OwnSql::GetBinaryValue(int row,char * fd_name,char * pBuf)
{
PROWS rows=NULL;
int len=0;
char * p=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return 0;
rows=(PROWS)res[row];
//查找列
for(int i=0;i<rows->cnt;i++)
{
if(!strcmp(rows->fields[i].field_name,fd_name))
{
len=(int)rows->fields[i].value_len;
if(pBuf==NULL)
break;
p=(char *)(rows->fields[i].filed_value);
memcpy(pBuf,p,len);
break;
}
}
return len;
}
int OwnSql::GetBinaryValue(int row,int fd_num,char * pBuf)
{
PROWS rows=NULL;
int len=0;
char * p=NULL;
len=res.GetCount();
//如果行号超过了范围,则返回0
if(row>=len)return NULL;
rows=(PROWS)res[row];
len=rows->fields[fd_num].value_len;
if(pBuf==NULL)
return len;
//直接返回此列的值
p=(char *)(rows->fields[fd_num].filed_value);
memcpy(pBuf,p,len);
return len;
}
调用方法:
char* host="localhost";
char* user="root";//用户名,一般为root
char* port ="3306";
char* passwd="root";//密码
char* dbname="choose"; //数据库名
char* charset = "GBK";//支持中文
char* Msg = "";//消息变量
mOwnSql=new OwnSql();
mOwnSql->Connect(host,user,passwd,dbname,3306);
mOwnSql->SelectDB(dbname);
mOwnSql->ExecuteQuery(“select * from my_table”);///my_table换成你自己的。
char * date=mOwnSql->GetDataTimeValue(0,0);