1. 程式人生 > >VC++6.0 MFC使用ODBC連結MySQL把圖片寫入blob欄位

VC++6.0 MFC使用ODBC連結MySQL把圖片寫入blob欄位

一、建立一個基於對話方塊的應用程式

1、工程取名ODBCPic,刪除自動建立的程式對話方塊資源中預設存在的靜態文字控制元件和兩個按鈕控制元件。

2、然後在該對話方塊資源上擺放兩個按鈕控制元件,ID(標題)分別為IDC_ADD_DATA(新增資料)、IDC_READ_DATA(讀出資料)。

3、在FileView裡打StdAfx.h裡新增標頭檔案#include <afxdb.h>

二、新增一個基於CRecordSet的類為CMyRecordset。

確認後選擇需要讀寫的資料表,VC++6.0會自動匯入表中的欄位,MyRecordset.h部分程式碼如下:

class CMyRecordset : public CRecordset
{
public:
	CMyRecordset(CDatabase* pDatabase = NULL);
	DECLARE_DYNAMIC(CMyRecordset)

// Field/Param Data
	//{{AFX_FIELD(CMyRecordset, CRecordset)
	CString	m_ID;    //資料表中的ID欄位,型別為varchar
	CLongBinary m_PIC;  //資料表中的PIC欄位,型別為mediumblob
	//}}AFX_FIELD


// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMyRecordset)
	public:
	virtual CString GetDefaultConnect();    // Default connection string
	virtual CString GetDefaultSQL();    // Default SQL for Recordset
	virtual void DoFieldExchange(CFieldExchange* pFX);  // RFX support
	//}}AFX_VIRTUAL

// Implementation
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
};

三、連結資料庫將本地圖片寫入mediumblob型別欄位

1、在ODBCPicDlg.cpp檔案中新增標頭檔案程式碼:

#include "MyRecordset.h"
#include <io.h>

2、連結資料庫寫入圖片程式碼:

void CODBCPicDlg::OnAddData() 
{
	// TODO: Add your control notification handler code here
	CString fileName;
	fileName = "C:\\Users\\Administrator\\Desktop\\1.jpg"; //圖片路徑
	if ((access(fileName, 0)) != 0)  //判斷檔案是否存在
	{
		AfxMessageBox("檔案不存在!");
		return;
	}

	CDatabase db;   //建立資料庫物件
	//連結資料庫DSN=資料來源名稱,UID=使用者名稱,PWD=密碼,字元編碼CharSet=GBK
	db.Open(NULL,FALSE,FALSE,"ODBC;DSN=MySQL;UID=root;PWD=123;CharSet=GBK");

	CMyRecordset db_set(&db); //繫結資料庫
	CString sql;
	sql = "SELECT * FROM ODBCPic";
	db_set.Open(CRecordset::snapshot,sql);
	db_set.AddNew();
	db_set.m_ID="第一張圖片";
	CFile file;
	file.Open("C:\\Users\\Administrator\\Desktop\\1.jpg",CFile::modeRead|CFile::typeBinary);//開啟指定檔案
	db_set.m_PIC.m_dwDataLength = file.GetLength();//m_blobfile為資料庫中blob欄位由classwizard對映過來的CLongBinary欄位
	HGLOBAL hGlobal = GlobalAlloc(GPTR,db_set.m_PIC.m_dwDataLength);
	db_set.m_PIC.m_hData = GlobalLock(hGlobal);
	file.Read(db_set.m_PIC.m_hData,db_set.m_PIC.m_dwDataLength);
	db_set.SetFieldDirty(&db_set.m_PIC,true);
	db_set.SetFieldNull(&db_set.m_PIC,false);
	GlobalUnlock(hGlobal);

	db_set.Update();//更新資料集
	db_set.Close();//關閉資料集
    db.Close();
	file.Close();//關閉檔案
}

注:由於VC++6.0是32位程式,所以將字元編碼設定為GBK:CharSet=GBK,資料表的字符集也必須設定為GBK!!!

3、讀出圖片程式碼:

void CODBCPicDlg::OnReadData() 
{
	// TODO: Add your control notification handler code here
	CDatabase db;  //建立資料庫物件
	//連結資料庫DSN=資料來源名稱,UID=使用者名稱,PWD=密碼,字元編碼CharSet=GBK
	db.Open(NULL,FALSE,FALSE,"ODBC;DSN=MySQL;UID=root;PWD=123;CharSet=GBK");
	
	CRecordset rs_set(&db);  //繫結資料庫
	CString sql;
	sql="select * from ODBCPic where ID = '第一張圖片'";
	rs_set.Open(CRecordset::forwardOnly,sql);
	if (rs_set.IsEOF())  //判斷游標是否到達資料集尾部
	{
		rs_set.Close();
		db.Close();
		AfxMessageBox("檢索結束,目標不存在!");
		return ;
	}
	while (!rs_set.IsEOF())
	{
		//CString PIC;
		CDBVariant CDBVariantPIC;  //建立可變資料
		rs_set.GetFieldValue("PIC",CDBVariantPIC); //用CDBVariantPIC物件來儲存欄位PIC的值
		int PICBuffLen=(int)CDBVariantPIC.m_pbinary->m_dwDataLength;  //獲取檔案二進位制長度
		if(PICBuffLen>0)
		{
			LPSTR PICtemp = (LPSTR)GlobalLock(CDBVariantPIC.m_pbinary->m_hData); //鎖定資料控制代碼記憶體
			GlobalUnlock(CDBVariantPIC.m_pbinary->m_hData);  //解鎖記憶體

			CString fileName;
			fileName = "C:\\Users\\Administrator\\Desktop\\第一張圖片.jpg";
			if ((access(fileName, 0)) != 0)  //判斷檔案是否存在
			{	
				CFile file;
				if (file.Open(fileName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary) == FALSE)
				{
					AfxMessageBox("檔案出錯!");
				}
				else
				{
					file.Write(PICtemp,PICBuffLen);  //寫入檔案
					file.Flush(); //將緩衝區的內容寫入檔案,並清空(如果不加檔案可能會少一點)
					file.Close();
				}
			}
			break; //如果記錄集只有一張圖片,寫完後跳出迴圈即可
			//rs_set.MoveNext(); //如果記錄集有多張圖片,寫完一張後將游標下移繼續寫
			//注:記得修改路徑為增量,否則最後一張圖片會將前面的圖片覆蓋
		}
	}
	rs_set.Close();
    db.Close();
}

示例程式:https://download.csdn.net/download/weixin_40026797/10775494