实战COM(06)----在COM中使用Ole DB连接数据库

    技术2022-05-11  137

    本文欢迎转载,唯请注明出处及作者 blackcolor@263.net---------------------------------------------------

                       实战COM(06)----在COM中使用Ole DB连接数据库

    一、建立组件1)创建一个进程内组件Step04,在创建的窗口“ATL COM AppWizard - Step 1 of 1”中选中“Allow merging of proxy/stub code”,加入一个“Simple Object”,取名为“Simple04”2)在该组件中加入以下方法:  HRESULT ConnectToSQL(void);  HRESULT MoveNext(void);  HRESULT GetAu_id([out, retval]BSTR * bAu_id);  HRESULT GetAu_lname([out, retval]BSTR * bAu_lname);  HRESULT GetAu_fname([out, retval]BSTR * bAu_fname);  HRESULT DisConnect(void);3)如果你对以上两个步骤还不熟悉,请参考“实战COM(02)----创建一个进程内组件”一文4)修改代码如下:

    文件:Simple04.h// Simple04.h : Declaration of the CSimple04#include <atldbcli.h> // 数据库操作

    #ifndef __SIMPLE04_H_#define __SIMPLE04_H_

    #include "resource.h"       // main symbols

    // 定义一个新类class CAuthors{public: // 数据--宽度来源于表Authors CHAR m_szAu_Id[11];   CHAR m_szAu_lName[40]; CHAR m_szAu_fName[20];  // 输出绑定 BEGIN_COLUMN_MAP(CAuthors)  COLUMN_ENTRY(1, m_szAu_Id)  COLUMN_ENTRY(2, m_szAu_lName)  COLUMN_ENTRY(3, m_szAu_fName) END_COLUMN_MAP()

     // 参数绑定 BEGIN_PARAM_MAP(CAuthors)  COLUMN_ENTRY(1, m_szAu_lName) END_PARAM_MAP()};

    /// CSimple04class ATL_NO_VTABLE CSimple04 :  public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CSimple04, &CLSID_Simple04>, public IDispatchImpl<ISimple04, &IID_ISimple04, &LIBID_STEP04Lib>{public: CSimple04() {  m_hr = E_FAIL;  // 初始化 }

    DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLE04)

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    BEGIN_COM_MAP(CSimple04) COM_INTERFACE_ENTRY(ISimple04) COM_INTERFACE_ENTRY(IDispatch)END_COM_MAP()

    // 加入变量public: CDataSource m_Connection; CSession m_session; CCommand<CAccessor<CAuthors> > m_Authors; HRESULT  m_hr;

    // ISimple04public: STDMETHOD(DisConnect)(void); STDMETHOD(MoveNext)(void); STDMETHOD(GetAu_fname)(/*[out, retval]*/BSTR * bAu_fname); STDMETHOD(GetAu_lname)(/*[out, retval]*/BSTR * bAu_lname); STDMETHOD(GetAu_id)(/*[out, retval]*/BSTR * bAu_id); STDMETHOD(ConnectToSQL)(void);};

    #endif ://__SIMPLE04_H_

    // 文件:Simple04.cpp// Simple04.cpp : Implementation of CSimple04#include "stdafx.h"#include "Step04.h"#include "Simple04.h"// 加入comutil支持#include <comutil.h>#pragma comment( lib, "comsupp.lib" )

    /// CSimple04

    // 连接到服务SQL器,并取回Authors数据STDMETHODIMP CSimple04::ConnectToSQL(){ // 如果已经建立了连接,先关闭 if(SUCCEEDED(m_hr)) {  m_session.Close();  m_Connection.Close();  // 关闭连接  m_hr = E_FAIL; }

     // 打开数据库 CDBPropSet dbinit(DBPROPSET_DBINIT); dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("GP2000"));  // 服务器名 dbinit.AddProperty(DBPROP_AUTH_USERID, OLESTR("sa"));   // 用户名 dbinit.AddProperty(DBPROP_AUTH_PASSWORD, OLESTR("123"));  // 密码 dbinit.AddProperty(DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, false); dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("pubs"));  // 数据库名 dbinit.AddProperty(DBPROP_INIT_LCID, (long)2052); dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4); m_hr = m_Connection.Open(_T("SQLOLEDB.1"), &dbinit); if (FAILED(m_hr)) return m_hr;  m_hr = m_session.Open(m_Connection); if (FAILED(m_hr))  {  m_Connection.Close();  return m_hr; } // 设置查询条件   strcpy(m_Authors.m_szAu_lName, "%h%");  // au_lname中包含"h"的作者 m_Authors.Open(m_session,             "select au_id, au_lname, au_fname from authors where au_lname like ?");

     return S_OK;}// 取结果集STDMETHODIMP CSimple04::MoveNext(){ if(SUCCEEDED(m_hr)) {  m_hr=m_Authors.MoveNext(); } else { // 关闭连接  DisConnect(); }

     return m_hr;}// 取数据STDMETHODIMP CSimple04::GetAu_id(BSTR *bAu_id){ if(SUCCEEDED(m_hr)) {  *bAu_id = _com_util::ConvertStringToBSTR(m_Authors.m_szAu_Id); }

     return S_OK;}

    STDMETHODIMP CSimple04::GetAu_lname(BSTR *bAu_lname){ if(SUCCEEDED(m_hr)) {  *bAu_lname = _com_util::ConvertStringToBSTR(m_Authors.m_szAu_lName); }

     return S_OK;}

    STDMETHODIMP CSimple04::GetAu_fname(BSTR *bAu_fname){ if(SUCCEEDED(m_hr)) {  *bAu_fname = _com_util::ConvertStringToBSTR(m_Authors.m_szAu_fName); }

     return S_OK;}

    STDMETHODIMP CSimple04::DisConnect(){ if(SUCCEEDED(m_hr)) {  m_session.Close();  m_Connection.Close();  // 关闭连接  m_hr = E_FAIL; }

     return S_OK;}

    二、建立客户端1)文件如下:// Client.cpp 文件

    #include <windows.h>#include <stdio.h>#include <winerror.h>// 加入comutil支持#include <comutil.h>#pragma comment( lib, "comsupp.lib" )

    // 包含com的定义文件,以下两个文件从step04中拷贝出来#include "../step04/step04.h"#include "../step04/step04_i.c"

    void main(){ ISimple04 * pISimple04=NULL;  // 我们定义的接口 BSTR  bAu_id, bAu_lname, bAu_fname; // 定义数据 char *pAu_id, *pAu_lname, *pAu_fname;

     // 初始化 HRESULT hr = CoInitialize(NULL); if(FAILED(hr)) {  printf("Coinitialize failed! hr=0x%x", hr);  return ; }

     // 创建COM对象 hr = CoCreateInstance(CLSID_Simple04, NULL, CLSCTX_ALL,                    IID_ISimple04, (void **)&pISimple04); if(FAILED(hr)) {  printf("create com failed! hr=0x%x", hr);  CoUninitialize();  return ; } // 连接SQL hr = pISimple04->ConnectToSQL(); if(FAILED(hr)) {  printf("pISimple04->ConnectToSQL() failed! hr=0x%x", hr);  pISimple04->Release();  CoUninitialize();  return ; } // 取数据 printf("au_id/tau_lname/t/t/tau_fname/n"); while (pISimple04->MoveNext() == S_OK) {  pISimple04->GetAu_id(&bAu_id);  pISimple04->GetAu_lname(&bAu_lname);  pISimple04->GetAu_fname(&bAu_fname);

      pAu_id = _com_util::ConvertBSTRToString(bAu_id);   pAu_lname = _com_util::ConvertBSTRToString(bAu_lname);   pAu_fname = _com_util::ConvertBSTRToString(bAu_fname);

      printf("%s/t%s/t/t/t%s/n", pAu_id, pAu_lname, pAu_fname);

      // 释放分配的内存  SysFreeString(bAu_id);  SysFreeString(bAu_lname);  SysFreeString(bAu_fname);  delete pAu_id;  delete pAu_lname;  delete pAu_fname; } // 断开连接 pISimple04->DisConnect(); pISimple04->Release(); CoUninitialize();

     return ;}

    三、说明1)你必须有访问SQL Server数据库pubs中的表authors的权限2)我使用了一些诸如CDataSource的类来访问SQL SERVER,你也可以直接使用SQL Provider提供的接口来访问数据库,不过使用SQL Provider提供的接口会更复杂一些。3)本文简单演示了一个SELECT的语句,可以将该SELECT换成一个存储过程,用Execute执行4)本文没有涉及到事务的处理,我将在下一篇说明如何在COM+中使用事务5)也可以将本文创建的组件配置成COM+的应用,可参考“实战COM(05)----创建一个COM+应用”


    最新回复(0)