是程式的最終效果,包含了資料的顯示,添加,修改,刪除這幾項資料庫操作的常用功能。
我的調試環境是xp,mysql版本是mysql4.0.23
1.安裝Mysql的ODBC驅動
從http://www.mysql.com上下載驅動程式
地址:http://dev.mysql.com/downloads/connector/odbc/3.51.html#win32
我是下載的Windows ZIP/Setup.EXE
下載到本機之後從zip包中解壓出setup.exe檔案,雙擊安裝,沒什麼可說的,完全的傻瓜式安裝
2.設定ODBC資料來源
配置MySQL的ODBC資料來源有兩種方法
第一種:手工設定
比較麻煩,但是確是比較安全的辦法。
步驟如下:
開始 -> 控制台 -> 管理工具 -> 資料來源 (ODBC),雙擊資料來源(ODBC)之後會出來如下的介面
點擊右上方的"添加"按鈕之後會出現如下的介面
可以看到,我們剛才安裝的驅動程式已經出現在列表中了,選中它,然後單擊完成,此時會出來下面的介面
按所示,填寫好各項串連所需要的資訊點擊“Test”可以進行測試,如果出現sucessful字樣就表示成功了
我解釋一下填寫的資訊:Data Source Name:縮寫就是DSN,中文翻譯過來就是資料來源名稱,就是給資料來源取個名,為了安全還是取英文名吧,省得出現意外。
Description:描述,可填可不填,我比較懶,就沒填,想填也行,就是描述一下這個資料來源是哪家的,幹啥用的等等,隨便吧Server:伺服器,不能省,我填的是localhost,如果你有遠程主機,不妨試試填上遠程主機的IP地址,我沒試過,不清楚User:使用者名稱,我本機資料庫用的是root,你們如果有別的就根據自己的情況填吧Password:密碼,我沒設定密碼,有則填之,沒有就留空Database:資料庫,這是一個listbox,可以自己填,也可以從下拉式清單中選,如果你前面的Server,User,Password都正確的話,下拉式清單中會出來可選的資料庫,這個就是我們要串連的資料庫資源。
解釋完畢,點了OK之後,我們就算設定完成了。
第二種:動態設定這種辦法是指在程式執行時才添加資料來源,SQLConfigDataSource是所用的方法,查msdn可以查到它的用法第一個參數一般設定成NULL就可以了,第二個參數我用的是ODBC_ADD_DSN,表示是新增資料來源第三個參數是驅動的名稱,在資料來源(ODBC)中抄過來就OK了第四個參數是連接字串,多個參數用分隔開,DSN就是資料來源名稱,UID是使用者名稱,PWD是密碼,SERVER是主機名稱,DATABASE是資料庫名稱,最後用兩個結束。
只要在程式中加上這一行,當程式執行到它時,就會在資料來源中加上你所設定的資料來源,並且可以在控制台 -> 管理工具 -> 資料來源(ODBC)中查到。二所示,裡面的odbctest和odbctestqqqq,前者就是動態建立的,後者是最初手工建立的。
SQLConfigDataSource(NULL,ODBC_ADD_DSN,"MySQL ODBC 3.51 Driver","DSN=odbctest UID=root PWD= SERVER=localhost DATABASE=odbc");
3.編寫串連程式我用的是VC6.0,VC這東西好是好,就是封裝得太多了,像我等這樣初來乍到之人一時半會是狗咬烏龜——找不到下口的地方下面我就按我的方式來說說,肯定有高手有更高明的辦法,不妨評論一二,也好讓我等開開眼界。
(1)。建立一個基於對話方塊的工程在VC中點擊菜單中 File -> New,在Projects的下拉式功能表中選擇MFC AppWizard (exe);在右上方的輸入框中填寫一個工程的名字,我取名叫ODBCTest;選擇一個存放目錄,我的是存在E:cODBCTest;點擊OK進入下一步,選擇基於對話方塊,然後點finish完成設定。
(2)。包含標頭檔切換到file view,在header files中找到stdafx.h,這是MFC第一個要包含的標頭檔,我們在裡面加上如下兩行,將odbc及資料庫操作所需的標頭檔引入到工程中。沒這兩個標頭檔編譯時間會出錯。
……
#include <odbcinst.h> #include "afxdb.h"// 用的時候把引號換成角括弧,編輯器自動給轉成了非源碼形式,鬱悶
//{{AFX_INSERT_LOCATION}}……
(3)。畫主體對話方塊
主體對話方塊是用來列表顯示資料,並放置其他動作入口的介面,在這個程式中,我們的主體對話方塊上會放置一個清單控制項和五個按鈕控制項。
在資源檢視上選擇對話方塊資源,然後繪製如如示的對話方塊
對圖上的控制項作一下說明
1)。列表,用的是list control,注意在styles中的view要設定成report(報表),如
2)。依次添加了三個按鈕,添加,修改,刪除。
在這裡做下說明,一般看網上的教程或是書,上面講的程式的編寫過程都是按步就班,沒有多餘的過程,因為作者都已經重新做了排版和設計工作,力求簡潔。但實際編程中確是不一樣的,常常要經過多次修改,重排,最佳化,所以這裡我打算按實際程式的編寫過程來說明,而不是按步就班的說明,力求還原程式編寫的全過程。作為一個初學VC的新手,相信有很多跟我一樣的新手也會遇到同樣的困難,沒關係,萬事開頭難。
一般的教程講到這裡就可能會去將後面所要用到的資源準備好,然後進行“系統的”編程。我這裡不這樣走,而是回到主視窗的編程上來,一個功能一個功能的實現。
1)。實現資料的列表顯示暈了,很多人肯定會暈了。這不扯淡嗎,我們的資料庫(庫名叫:odbc)裡啥東西都還沒有,顯示啥呀。
沒關係,好在俺也搞過Mysql幾年,別的不會,管理Mysql的工具倒是知道不少,比如:EMS,phpMyAdmin,DBtools……
我為了簡單就用了phpMyadmin這個工具,這個工具需要在本地安裝了php和mysql才能使用,如果本地沒有裝php就用不了了,不過沒關係,去下載一個EMS也不錯,非常強大的工具,華麗的介面,豐富的功能。用過SQL server的可能更習慣於使用DBTools Manager,這也是個強大的工具,值得一試。
二毛說,學VC,在還沒有入門之前機器上就會有一堆的工具。初始還不信,現在我信了,這不,剛學沒幾天,機器上就跑上了VC,msdn,另外還有一堆的入門電子書,閱讀器,視頻播放軟體……既然已經有這麼多了,再多幾個也無所謂了。
跑題了哈,我先刹車倒回來,接著講資料的顯示,第一步:在odbc庫中建一張表list,都怪我,這庫名取得有點誤導觀眾,這裡再次申明一下,這裡的odbc是我建的一個MySQL資料庫,不是那個該死的縮寫。下面是建好之後的表
id:是一個自增,非負的10位整型欄位,用來存放使用者的ID
name:是一個40位變長的字串,用來存放使用者名稱
age:是一個3位的小整型欄位,因為沒有啟用非負設定,最大可以到127,此欄位存放使用者年齡
這就是list表的結構,然後我們在表中插入幾條初始資料,用來顯示。
phpMyAdmin的使用我就不多說了,這屬於工具的使用,不在本文的說明範圍之內。
添加好資料之後,我們可以在phpmyadmin中瀏覽到它們,如:
2)。編程顯示資料列表
回到VC中來,在類別檢視中,找到CODBCTestDlg並展開,找到裡面的OnInitDialog()方法,此方法是對話方塊的初始化方法,我的最初想法就是在這裡面完成資料庫的串連,查詢,並輸出資料到列表中。於是我寫了如下的代碼
CDatabase db;
db.Open(NULL,FALSE,FALSE,"ODBC;DSN=odbctest;UID=root;PWD=");
CRecordset rs( &db );
rs.Open( CRecordset::forwardOnly, _T("SELECT * FROM list order by id Asc"));
short nFields = rs.GetODBCFieldCount();
while(!rs.IsEOF())
{
CString varID;
rs.GetFieldValue("id", varID);
m_list.InsertItem(0,varID);
CString varName;
rs.GetFieldValue("name", varName);
m_list.SetItemText(0, 1, varName);
CString varAge;
rs.GetFieldValue("age", varAge);
m_list.SetItemText(0, 2, varAge);
rs.MoveNext();
}
rs.Close();
db.Close();
但後來發現有問題,因為在後面每添加一條記錄之後都需要更新列表,重新輸出,這就需要再次寫一段跟上面一模一樣的代碼,我靠,這不浪費時間嗎。於是,我將上面的這段代碼放到了類的一個方法中。步驟如下:
1)。在類別檢視中選中CODBCTestDlg,點右建,選擇新增function,然後建立一個void GetRecord()的方法,如
2)。將上面的代碼放到方法中,最終的代碼如下
void CODBCTestDlg::GetRecord()
{
m_list.DeleteAllItems();
CDatabase db;
db.Open(NULL,FALSE,FALSE,"ODBC;DSN=odbctest;UID=root;PWD=");
CRecordset rs( &db );
rs.Open( CRecordset::forwardOnly, _T("SELECT * FROM list order by id Asc"));
//short nFields = rs.GetODBCFieldCount();// 此行原是用來遍曆表中欄位,現在沒有用上
while(!rs.IsEOF())
{
CString varID;
rs.GetFieldValue("id", varID);
m_list.InsertItem(0,varID);
CString varName;
rs.GetFieldValue("name", varName);
m_list.SetItemText(0, 1, varName);
CString varAge;
rs.GetFieldValue("age", varAge);
m_list.SetItemText(0, 2, varAge);
rs.MoveNext();
}
rs.Close();
db.Close();
m_list.AdjustColumnWidth();//新增了一個CMyListCtrl類,這是裡面我新增的一個方法,用來自適應資料寬度
}
這樣,以後在需要重新取列表資料時就可以調用此方法了,這就叫重用。
ODBC串連資料庫,有兩個類是需要關心的,第一個是CDatabase,另一個是CRecordset
前者用於資料庫連接的建立,後者用於資料集的取得
建立串連,用如下的代碼來實現
CDatabase db;//聲明一個對象
db.Open(NULL,FALSE,FALSE,"ODBC;DSN=odbctest;UID=root;PWD=");// 串連資料來源
至於為什麼這麼寫,查msdn吧
取資料集合
CRecordset rs( &db );// 綁定資料來源
rs.Open( CRecordset::forwardOnly, _T("SELECT * FROM list order by id Asc"));//查詢資料
要執行sql,我並沒有用ODBC提供的方法,而是用更直接的辦法
CString sql;
sql.Format("update list set name='%s', age='%s' where id=%d",str_name, str_age, item_id);
db.ExecuteSQL(sql);
這種辦法的好處是可以不用從CRecordSet繼承新類,且對我這樣瞭解一部分sql的新手比較直觀。