mysql 存 binary/blob

一般我们对数据库的操作到时直接存与读基本类型的数据, 如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="" />
 
 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值