项目展示
效果
工程文件
项目链接:https://download.csdn.net/download/weixin_45525272/12637832
ActiveX Data Objects
一种程序对象,用于表示用户数据库中的数据结构和所包含的数据。在Microsoft Visual Basic编辑器中,可以使用ADO对象以及ADO的附加组件(称为Microsoft ADO Extensions for DLL and Security(ADOX))来创建或修改表和查询、检验数据库、或者访问外部数据源。还可在代码中使用ADO来操作数据库中的数据。
编程模型
连接数据源 (Connection),可选择开始事务。
可选择创建表示 SQL 命令的对象 (Command)。
可选择指定列、表以及 SQL 命令中的值作为变量参数 (Parameter)。
执行命令(Command、Connection 或 Recordset)。
如果命令以行返回,将行存储在存储对象中 (Recordset)。
可选择创建存储对象的视图以便进行排序、筛选和定位数据 (Recordset)。
编辑数据。可以添加、删除或更改行、列 (Recordset)。
在适当情况下,可以使用存储对象中的变更对数据源进行更新 (Recordset)。
在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务 (Connection)。
使用方法
一旦安装了ADO,在VB的工程->引用对话框中你就可以看到象下图所示的东西了:
选择 “ActiveX Data Objects 1.5 Library” (ADODB).在其下的 "ADO Recordset 1.5 Library"是一个客户端的版本(ADOR),它定义了有聚的数据访问对象。ADOR 对于客户端的数据访问来说是足够的了,因为你不需要Connection对象来建立与远程数据源的联系。
如果你想要访问更多的外部数据源,你需要安装这些外部数据源自己的OLE DB Provider,就象你需要为新的数据库系统安装新的ODBC驱动程序一样。如果该外部数据源没有自己的OLE DB Provider,你就得使用OLE DB SDK来自己为这个外部数据源创建一个OLE DB Provider了。这已不是本文讨论的范围了。
示例
下面的示例代码以Northwinds数据库作为远程数据源,然后用ADO来访问它。首先在控制面板中打开“32位数据源”,单击“添加”按钮。在弹出的对话框中选择 “Microsoft Access Driver (*.mdb)” 作为数据源驱动程序。
然后按下图所示,在对话框中填写下面的内容
选择数据库Northwinds所在路径。单击完成,退出ODBC设备管理器。
启动一个新的VB工程,在窗体的Load事件中输入下面的代码:
Private Sub Form_Load() Dim cn As ADODB.Connection Set cn = New ADODB.Connection 'Set Connection properties cn.ConnectionString = "DSN=RDC Nwind;UID=;PWD=;" cn.ConnectionTimeout = 30 cn.Open If cn.State = adStateOpen Then _ MsgBox "Connection to NorthWind Successful!" cn.Close End Sub
按F5运行程序,看看,一个消息框弹出来告诉你连接成功了。请注意,这里我特别注明了是ADODB.Connection,而不是ADOR.Connection,这样做是为了将二者区分开(如果你引用了ADODB和ADOR的话,这样做很有必要)。连接字符串看上去同RDO的连接字符串差不多。事实上,二者确实差不多。
如果我们要访问一个SQL server数据库,你的Connection代码看上去应象下面所示:
'设置连接属性cn.Provider = “MSDASQL”
cn.ConnectionString = “driver={SQL Server};” &
“server=prod1;uid=bg;pwd=;database=main”
cn.Open
"Provider"属性指向SQL Server的OLE DB Provider.
回到我们的示例程序,让我们创建一个Recordset对象来访问“Orders”表,并从该表的"ShipCountry"字段中产生头十个不重复的国家名。修改窗体Load事件中的代码,让它看上去象下面这样。
Private Sub Form_Load() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim sSQL As String Dim sOut As String Dim Count As Integer Set cn = New ADODB.Connection Set rs = New ADODB.Recordset ' Set properties of the Connection. cn.ConnectionString = "DSN=RDC Nwind;UID=;PWD=;" cn.ConnectionTimeout = 30 cn.Open If cn.State = adStateOpen Then _ MsgBox "Connection to NorthWind Successful!" sSQL = "SELECT DISTINCT Orders.ShipCountry FROM Orders" Set rs = cn.Execute(sSQL) 'Enumerate the recordset sOut = "" For Count = 1 To 10 sOut = sOut & rs("ShipCountry") & vbCrLf rs.MoveNext Next Count MsgBox sOut, vbExclamation, "ADO Results" cn.Close End Sub
运行程序后,你会看到如下图所示的消息框。
不幸的是你需要创建一个独立的Recordset对象,该对象拥有自己的Connection属性,
就象下面的代码所示:
Private Sub Form_Load() Dim rs As ADODB.Recordset Dim sSQL As String Dim sOut As String Dim Count As Integer Set rs = New ADODB.Recordset sSQL = "SELECT DISTINCT Orders.ShipCountry FROM Orders" rs.Open sSQL, "DSN=RDC Nwind;UID=;PWD=;", adOpenDynamic 'Report Recordset Connection information MsgBox rs.ActiveConnection, , "Connection Info" 'Enumerate the recordset sOut = "" For Count = 1 To 10 sOut = sOut & rs("ShipCountry") & vbCrLf rs.MoveNext Next Count MsgBox sOut, vbExclamation, "ADO Results" rs.Close End Sub
上面代码返回的结果同前例一样,但是本代码中的Recordset是独立的。这一点是DAO和RDO做不到的。Recordset对象的Open方法打开一个代表从SQL查询返回的记录的游标。虽然你可以用Connection对象同远程数据源建立连接,但请记住,在这种情况下,Connection对象和Recordset对象是平行的关系。
总结
本文仅向你介绍了ADO强大的功能的冰山一角。微软承诺,在将来ADO将会取代DAO和RDO。所以现在你应该考虑将你的数据访问代码投向ADO的怀抱。因为ADO的语法同现有的语法差不多。也许微软或第三方会在将来开发出转换向导来简化这一转换过程。从现在起,你就开发纯ADO代码的程序。你也可以继续使用DAO或RDO代码来开发你的程序,但落伍的感觉总是不好的。
MFC—ADO类应用设计
头文件
#pragma once #import "C:\Program Files\Common Files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF") class CADOConnect { public: CADOConnect(); virtual~CADOConnect(); _ConnectionPtr m_pConnection; // 对象智能指针连接操作数据库 _RecordsetPtr m_pRecordPtr; // 对象指针(记录集) // 初始化连接数据库,执行查询,执行SQL语句,断开连接 // 初始化连接数据库,执行查询,执行SQL语句,断开连接 void OnInitDBConnect(); _RecordsetPtr &GetRecordSet(_bstr_t bstrSQL); BOOL ExecuteSQL(_bstr_t bstrSQL); void ExitConnect(); };
源文件
#include "stdafx.h" #include "ADOConnect.h" CADOConnect::CADOConnect() { } CADOConnect::~CADOConnect() { } void CADOConnect::OnInitDBConnect() { // 创建connection对象 m_pConnection.CreateInstance("ADODB.Connection"); // 设置字符串 _bstr_t strConnect = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Student;Data Source=.";// Catalog数据库名称,Data数据库 .表示本地数据库 // 连接数据库 双引号里写对应连接数据库的账号和密码 m_pConnection->Open(strConnect, "", "", adModeUnknown); } _RecordsetPtr & CADOConnect::GetRecordSet(_bstr_t bstrSQL) { try { if (m_pConnection == NULL) // 连接对象不存在 OnInitDBConnect(); m_pRecordPtr.CreateInstance(__uuidof(Recordset)); // 创建记录集对象 // 执行查询,等待记录集 m_pRecordPtr->Open(bstrSQL, m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); } catch (_com_error e) // 捕捉异常 { AfxMessageBox(e.Description()); } return m_pRecordPtr; // 返回记录集 } BOOL CADOConnect::ExecuteSQL(_bstr_t bstrSQL) { try { if (m_pConnection == NULL) { OnInitDBConnect(); } m_pConnection->Execute(bstrSQL, NULL, adCmdText); return true; } catch (_com_error e) { AfxMessageBox(e.Description()); return false; } } void CADOConnect::ExitConnect() { if (m_pConnection != NULL) { m_pRecordPtr->Close(); // 关闭记录 m_pConnection->Close(); // 关闭连接 } // 清除缓存 ::CoUninitialize(); }
用的时候这样写
比如这是上图登陆按钮的代码
void CStudentDlg::OnBnClickedButtonlogo() { // TODO: 在此添加控件通知处理程序代码 CADOConnect adoConn; CString str, sqlstr; int iCleck; iCleck = ((CComboBox*)GetDlgItem(IDC_COMBOCLECK))->GetCurSel(); ((CComboBox*)GetDlgItem(IDC_COMBOCLECK))->GetLBText(iCleck, str); //AfxMessageBox(str); UpdateData(TRUE); if (m_strname.IsEmpty() || m_strpassword.IsEmpty()) { MessageBox(L"对不起:用户名或密码不能为空?", L"错误", MB_ICONERROR); GetDlgItem(IDC_EDITUSER)->SetFocus(); // 将光标跳到输入用户名编辑框控件 } GetDlgItem(IDC_EDITUSER)->SetFocus(); try{ sqlstr.Format(L"select *from UserTables where strname = '%s' and strpassword = '%s' and strcleck = '%s'", m_strname, m_strpassword, str); _bstr_t vSQL; vSQL = (_bstr_t)sqlstr; _RecordsetPtr m_recordSet; m_recordSet = adoConn.GetRecordSet(vSQL); CString str1, str2, str3; str1 = (LPCSTR)(_bstr_t)(m_recordSet->GetCollect("strname")); str2 = (LPCSTR)(_bstr_t)(m_recordSet->GetCollect("strpassword")); str3 = (LPCSTR)(_bstr_t)(m_recordSet->GetCollect("strcleck")); // 删除字符串右空格 str1.TrimRight(); str2.TrimRight(); str3.TrimRight(); if (str1 == m_strname || str2 == m_strpassword || str3 == str) { MessageBox(L"恭喜您,登录成功!", L"正确", MB_ICONINFORMATION); this->EndDialog(TRUE); } } catch (...) { MessageBox(L"对不起:操作失败?", L"错误", MB_ICONERROR); m_strname = L""; m_strpassword = L""; GetDlgItem(IDC_EDITUSER)->SetFocus(); UpdateData(false); } }