一般我们对数据库的操作到时直接存与读基本类型的数据, 如int bigint char 等等, 但是当数据量很大时,或者你的字段很多时就会操作很不方便
这里就用到了数据库存储二进制的方法
这里也不多什么理论。 就直接附上代码给大家参考
DbToBinary.h 文件
#pragma once
#include <iostream>
#include <string>
//--------------------------------------------------------------------------------------------------
//序列化字符串方法2
class CMyFileBinStream;
class IDBSave
{
public:
IDBSave(){};
virtual ~IDBSave(){};
// 注意char 类型和string类型不可以有符号"'";
virtual CMyFileBinStream* Save( CMyFileBinStream& f ) = 0;
virtual CMyFileBinStream* Load( CMyFileBinStream& f ) = 0;
};
class CMyFileBinStream
{
public:
CMyFileBinStream();
~CMyFileBinStream();
public:
// 获得序列化后的字符串
// const std::string getInfo();
//-----------------------------------------------------------------------------------------------------
template< typename T>
CMyFileBinStream& operator<< ( T nValue )
{
unsigned int nLength = sizeof( T );
_MonitorMemory( nLength );
memcpy( m_pMemory + m_nPos, &nValue, nLength );
m_nPos += nLength;
return *this;
}
template<>
CMyFileBinStream& operator<< <std::string> ( std::string stValue )
{
stValue = "'" + stValue + "'";
unsigned int nLength = stValue.length();
_MonitorMemory( nLength );
memcpy( m_pMemory + m_nPos, stValue.c_str(), nLength );
m_nPos += nLength;
return *this;
}
template<>
CMyFileBinStream& operator<< <char*> ( char* gcValue )
{
std::string stTmp = gcValue;
stTmp = "'" + stTmp + "'";
unsigned int nLength = stTmp.length();
_MonitorMemory( nLength );
memcpy( m_pMemory + m_nPos, stTmp.c_str(), nLength );
m_nPos += nLength;
return *this;
}
const std::string SaveToDB( IDBSave* p );
//--------------------------------------------------------------------------------------------
template< typename T>
CMyFileBinStream& operator>> ( T* nValue )
{
unsigned int nLength = sizeof( T );
memcpy( nValue, m_pMemory + m_nPos, nLength );
m_nPos += nLength;
return *this;
}
template<>
CMyFileBinStream& operator>> <std::string>( std::string* stValue )
{
std::string stTmp = m_pMemory + m_nPos;
std::string::size_type pos = stTmp.find("'");
if ( pos != 0 )
{
return *this;
}
pos = stTmp.find("'", pos+1);
unsigned int nLength = pos - 1;
char* pInfo = new char[nLength + 1];
memset( pInfo, 0, nLength + 1 );
memcpy( pInfo , m_pMemory + m_nPos +1, nLength );
*stValue = pInfo;
m_nPos += (pos + 1);
delete []pInfo;
pInfo = NULL;
return *this;
}
template<>
CMyFileBinStream& operator>> <char> ( char* gcValue )
{
std::string stTmp = m_pMemory + m_nPos;
std::string::size_type pos = stTmp.find("'");
if ( pos != 0 )
{
return *this;
}
pos = stTmp.find( "'", pos + 1 );
unsigned int nLength = pos - 1;
memcpy( gcValue, m_pMemory + m_nPos + 1, nLength );
m_nPos += (pos + 1 );
return *this;
}
CMyFileBinStream* LoadData( IDBSave* p, const char* pData, unsigned int nNum );
protected:
// 处理内存
void _MonitorMemory( unsigned int nNum );
private:
unsigned int m_MaxSize;
char* m_pMemory;
unsigned int m_nPos;
};
<pre name="code" class="cpp">DbToBinary.cpp
#include "DbToBinary.h"
#include "DatabaseInstance.h"
CMyFileBinStream:: CMyFileBinStream()
{
m_nPos = 0;
m_MaxSize = 512;
m_pMemory = new char[m_MaxSize];
}
CMyFileBinStream:: ~CMyFileBinStream()
{
delete m_pMemory;
m_pMemory = NULL;
}
void CMyFileBinStream:: _MonitorMemory( unsigned int nLength )
{
if ( m_nPos + nLength >= m_MaxSize)
{
char* pTmpMemory = new char[m_MaxSize];
unsigned int nTempSize = m_MaxSize;
memcpy( pTmpMemory, m_pMemory, m_MaxSize );
delete[]m_pMemory;
m_MaxSize += m_MaxSize;
m_pMemory = new char[m_MaxSize];
memcpy( m_pMemory, pTmpMemory, nTempSize );
}
}
const std::string CMyFileBinStream:: SaveToDB( IDBSave* p )
{
m_nPos = 0;
memset( m_pMemory, 0, m_MaxSize );
p->Save( *this );
return DatabaseInstance::GetInstance()->processToDbString( m_pMemory, m_nPos ); // 这里是将二进制流转换为mysql可识别的, 具体怎么转可以查网站
}
CMyFileBinStream* CMyFileBinStream::LoadData( IDBSave* p, const char* pData, unsigned int nNum )
{
if( p == NULL )
{
return NULL;
}
if ( m_nPos != 0)
{
m_nPos = 0;
}
memset( m_pMemory, 0, m_MaxSize );
memcpy( m_pMemory, pData, nNum );
p->Load( *this );
return this;
}
main.cpp
// main.cpp文件
#include <iostream>
#include "DatabaseInstance.h"
#include "DbToBinary.h"
#include "xString.h"
// 由于是单独抽离出来的我就不再注意机构的优越性我直接在全局声明对象
struct testBlob:public IDBSave
{
testBlob()
{
a = 0;
memset(gcName, 0, 20);
}
int a;
char gcName[20];
virtual CMyFileBinStream* Save( CMyFileBinStream& f )
{
f<< a << gcName;
return &f;
}
virtual CMyFileBinStream* Load( CMyFileBinStream& f )
{
f>> &a >> gcName;
return &f;
}
};
DatabaseInstance database;
int main()
{
// 打开数据库
database.open( "testdb", "localhost", "root", "123456" );
testBlob test;
test.a = 10;
xStringConvert::o_strncpy(test.gcName, "helloworld", 11);
printf("插入之前信息\n id:%d, test1.a : %d, test1.name:%s\n", 1988, test.a, test.gcName);
CMyFileBinStream* pStream = database.getBinStream();
if( pStream == NULL ) return 0;
const std::string blobInfo= pStream->SaveToDB(dynamic_cast<IDBSave*>(&test));
char gcSql[512] = {0};
xStringConvert::stringFormat( gcSql, 512, "insert into testinfo(id, testBlob) values(%d, '%s')",1988, blobInfo.c_str());
database.execSQL(gcSql);
CppMySQLQuery mySqlQuery;
database.querySQL("select * from testinfo where id = 1988", mySqlQuery );
int id = mySqlQuery.getIntField("id");
const char* pBloBInfo = mySqlQuery.getStringField("testBlob");
unsigned int nLength = mySqlQuery.GetDataSize("testBlob");
if( pBloBInfo == NULL ) return 0;
testBlob test1;
pStream->LoadData(dynamic_cast<IDBSave*>(&test1), pBloBInfo, nLength );
printf("查询结果\n id:%d, test1.a : %d, test1.name:%s", id, test1.a, test1.gcName);
getchar();
return 0;
}
一下是插入mysql后 再读出来时的数据
<img src="https://img-blog.csdn.net/20150629225857578?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFjaHVhbmZlaV9j/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />