以前做数据库课程设计的时候也用到过,隔了这么久,又有点小小的忘记了,经过这几天的摸索,终于彻底搞清楚了脉络,特此记下,为以后的应用做铺垫。
本文使用的是MFC和access数据库进行的连接应用,其实换成sql server数据库也是类似的(只需改动连接字符串中的provider字段)。
首先在VC++的开发环境中添加一个C++的类,命名为:CDateBaseProcess。自动生成两个相应的文件:DateBaseProcess.h和DateBaseProcess.cpp文件。
一, 在DateBaseProcess.h文件中
1.定义三个变量:
public: _ConnectionPtr m_pConnection; //连接指针 _RecordsetPtr m_pRecordset; //记录集指针 _CommandPtr m_pCommand; //命令指针
2.定义四个函数:
public: bool InitConnect(); //初始化连接 void CloseConnect(); //关闭连接 void DisplayRule(_RecordsetPtr &pRec); //显示规则集 bool AddRule(CString strType,CString strContext);//添加规则
二,在DateBaseProcess.cpp文件中
bool CDateBaseProcess::InitConnect() //初始化连接 { m_pConnection.CreateInstance(__uuidof(Connection));///创建Connection对象 m_pRecordset.CreateInstance(__uuidof(Recordset)); //创建Recordset对象 m_pCommand.CreateInstance(__uuidof(Command)); //创建Command对象 m_pConnection->put_ConnectionTimeout(long(5)); try { m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=SpamFilterDatabase.mdb","","",adModeUnknown);///连接数据库 m_pCommand->ActiveConnection = m_pConnection; } catch(_com_error e) { return FALSE; } return TRUE; }
2,函数CloseConnect():
在对数据操作完成之后关闭连接。
void CDateBaseProcess::CloseConnect() { if(m_pConnection->State) { m_pConnection->Close(); } m_pConnection= NULL; if (m_pRecordset->State) { m_pRecordset->Close(); } m_pRecordset = NULL; if (m_pCommand->State) { m_pCommand = NULL; } }
4,函数DisplayRule(_RecordsetPtr &pRec):
用于提取要显示的内容,此函数的设计是本文的核心内容,通过传引用型的记录集参数,来获取要显示的所有内容。而显示的方式,可以由调用这个函数的函数自己定义,从而实现了数据库操作和应用程序显示方式之间的独立性。
void CDateBaseProcess::DisplayRule(_RecordsetPtr &pRec) { this->InitConnect(); m_pCommand->CommandText = "select * from ruleTable"; m_pRecordset = m_pCommand->Execute(NULL,NULL,adCmdText); pRec = m_pRecordset; }
注意:这里最后不能调用CloseConnect()函数去关闭连接,因为一旦关闭了连接,则在应用程序中对记录集的操作也将是无效。所以应该在调用这个函数的函数最后调用CloseConnect()函数去关闭连接。
5,函数AddRule(CString strType,CString strContext):
用于向数据库中添加一条记录,在这个函数外部并不需要任何对记录集的操作,所以可以不需要传记录集的参数。
bool CDateBaseProcess::AddRule(CString strType,CString strContext) { this->InitConnect(); CString strSql = NULL; strSql.Format(_T("select * from ruleTable where type = '%s'and context = '%s'"),strType,strContext); m_pCommand->CommandText = (_bstr_t)strSql; m_pRecordset = m_pCommand->Execute(NULL,NULL,adCmdText); if (m_pRecordset->adoEOF) { strSql.Format(_T("insert into ruleTable(type,context) values('%s','%s')"),strType,strContext); m_pCommand->CommandText = (_bstr_t)strSql; m_pCommand->Execute(NULL,NULL,adCmdText); CloseConnect(); return true; } else //已经存在不能重复输入 { CloseConnect(); return false; } }
注意:这里掉用了CloseConnect()函数,原因如上所述,在函数外部不需要操纵数据库。
列出最后两个函数的用意是介绍两种不同类型的数据库操作:查询和更新(添加,删除,修改)。以及这两种不同操作要注意的事项。
三,操作CDateBaseProcess类的类:
1.在头文件中包含#include "DateBaseProcess.h"
2.定义一个CDateBaseProcess的对象,以及记录集指针(如果不需要对数据进行查询或对记录集进行操作的话可以不用定义记录集指针)。
_RecordsetPtr m_pRecordset; //结果集指针 CDateBaseProcess m_db; //数据库操作类实例
m_db.DisplayRule(m_pRecordset); while(!m_pRecordset->adoEOF) { varType = m_pRecordset->GetCollect("type"); varContext = m_pRecordset->GetCollect("context"); m_ruleLCtrl.InsertItem(i,(LPCTSTR)varType.pbstrVal); m_ruleLCtrl.SetItemText(i,1,(LPCTSTR)varContext.pbstrVal); m_pRecordset->MoveNext(); i++; } m_db.CloseConnect();
注意:这里一定要调用了CloseConnect()函数
4.添加操作:
UpdateData(); CString strType = NULL; m_typeCBox.GetLBText(m_typeCBox.GetCurSel(),strType); if (!m_contextEdit.IsEmpty()) { if (m_db.AddRule(strType,m_contextEdit)) { MessageBox(_T("规则添加成功!")); OnPaint(); } else { MessageBox(_T("添加失败,该规则已存在,不能重复添加!")); } } else { MessageBox(_T("内容不能为空!")); } UpdateData(FALSE);