데이터베이스 특성을 사용하여 데이터 액세스 단순화

이 항목에서는 데이터베이스 특성을 사용하여 데이터베이스 작업을 간소화하는 방법을 보여 줍니다.

데이터베이스에서 정보에 액세스하는 기본 방법은 데이터베이스의 특정 테이블에 대한 명령(또는 테이블) 클래스 및 사용자 레코드 클래스를 만드는 것입니다. 데이터베이스 특성은 이전에 수행해야 했던 템플릿 선언 중 일부를 간소화합니다.

데이터베이스 특성의 사용을 설명하기 위해 다음 섹션에서는 두 개의 동등한 테이블 및 사용자 레코드 클래스 선언을 보여 줍니다. 첫 번째는 특성을 사용하고 두 번째는 OLE DB 템플릿을 사용합니다. 이러한 선언 코드는 일반적으로 테이블 또는 명령 개체(예: Authors.h)에 이름이 지정된 헤더 파일에 배치됩니다.

두 파일을 비교하면 특성을 사용하는 것이 얼마나 간단한지 확인할 수 있습니다. 차이점은 다음과 같습니다.

  • 특성을 사용하면 한 클래스 CAuthors만 선언하면 됩니다. 단, 템플릿을 사용하는 경우 다음 두 CAuthorsNoAttrAccessor CAuthorsNoAttr클래스를 선언해야 합니다.

  • db_source 특성이 지정된 버전의 호출은 템플릿 선언의 OpenDataSource() 호출과 동일합니다.

  • db_table 특성이 지정된 버전의 호출은 다음 템플릿 선언과 동일합니다.

    class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
    
  • 특성이 지정된 버전의 호출은 db_column 템플릿 선언의 열 맵(참조 BEGIN_COLUMN_MAP ... END_COLUMN_MAP)과 동일합니다.

특성은 사용자 레코드 클래스 선언을 삽입합니다. 사용자 레코드 클래스는 템플릿 선언에서와 같습니다 CAuthorsNoAttrAccessor . 테이블 클래스인 CAuthors경우 삽입된 사용자 레코드 클래스의 이름이 지정 CAuthorsAccessor되며 삽입된 코드에서만 해당 선언을 볼 수 있습니다. 자세한 내용은 사용자 레코드의 "특성 삽입 사용자 레코드 클래스"를 참조하세요.

특성 코드와 템플릿 코드 모두에서 .를 사용하여 CDBPropSet::AddProperty행 집합 속성을 설정해야 합니다.

이 항목에서 설명하는 특성에 대한 자세한 내용은 OLE DB 소비자 특성을 참조 하세요.

참고 항목

아래 예제를 컴파일하려면 다음 include 명령문이 필요합니다.

#include <atlbase.h>
#include <atlplus.h>
#include <atldbcli.h>

특성을 사용하는 테이블 및 접근자 선언

다음 코드는 테이블 클래스를 호출 db_source 합니다 db_table . db_source 는 사용할 데이터 원본 및 연결을 지정합니다. db_table 는 테이블 클래스를 선언하는 적절한 템플릿 코드를 삽입합니다. db_column 열 맵을 지정하고 접근자 선언을 삽입합니다. ATL을 지원하는 모든 프로젝트에서 OLE DB 소비자 특성을 사용할 수 있습니다.

특성을 사용하는 테이블 및 접근자 선언은 다음과 같습니다.

//////////////////////////////////////////////////////////////////////
// Table and accessor declaration using attributes
// authors.h
//////////////////////////////////////////////////////////////////////

// Table class declaration
// (Note that you must provide your own connection string for db_source.)
[
   db_source(L"your connection string"),
   db_table("Authors")
]
class CAuthors
{
public:
   DBSTATUS m_dwAuIDStatus;
   DBSTATUS m_dwAuthorStatus;
   DBSTATUS m_dwYearBornStatus;
   DBLENGTH m_dwAuIDLength;
   DBLENGTH m_dwAuthorLength;
   DBLENGTH m_dwYearBornLength;
   [db_column("1", status = "m_dwAuIDStatus", length = "m_dwAuIDLength")] LONG m_AuID;
   [db_column("2", status = "m_dwAuthorStatus", length = "m_dwAuthorLength")] TCHAR m_Author[51];
   [db_column("3", status = "m_dwYearBornStatus", length = "m_dwYearBornLength")] SHORT m_YearBorn;
   void GetRowsetProperties(CDBPropSet* pPropSet)
   {
      pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_IRowsetChange, true);
   }
};

템플릿을 사용하는 테이블 및 접근자 선언

템플릿을 사용하는 테이블 및 접근자 선언은 다음과 같습니다.

//////////////////////////////////////////////////////////////////////
// Table and user record class declaration using templates
// authors.h
//////////////////////////////////////////////////////////////////////

// User record class declaration
class CAuthorsNoAttrAccessor
{
public:
   DWORD m_dwAuIDStatus;
   DWORD m_dwAuthorStatus;
   DWORD m_dwYearBornStatus;
   DWORD m_dwAuIDLength;
   DWORD m_dwAuthorLength;
   DWORD m_dwYearBornLength;
   LONG m_AuID;
   TCHAR m_Author[51];
   SHORT m_YearBorn;
   void GetRowsetProperties(CDBPropSet* pPropSet)
   {
      pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_IRowsetChange, true);
   }
   HRESULT OpenDataSource()
   {
      CDataSource _db;

HRESULT hr;
      hr = _db.OpenFromInitializationString(L"your connection string");
      if (FAILED(hr))
      {
#ifdef _DEBUG
         AtlTraceErrorRecords(hr);
#endif
         return hr;
      }
      return m_session.Open(_db);
   }
   void CloseDataSource()
   {
      m_session.Close();
   }
   operator const CSession&()
   {
      return m_session;
   }
   CSession m_session;
   BEGIN_COLUMN_MAP(CAuthorsNoAttrAccessor)
      COLUMN_ENTRY_LENGTH_STATUS(1, m_AuID, m_dwAuIDLength, m_dwAuIDStatus)
      COLUMN_ENTRY_LENGTH_STATUS(2, m_Author, m_dwAuthorLength, m_dwAuthorStatus)
      COLUMN_ENTRY_LENGTH_STATUS(3, m_YearBorn, m_dwYearBornLength, m_dwYearBornStatus)
   END_COLUMN_MAP()
};
class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
{
public:
   HRESULT OpenAll()
   {
HRESULT hr;
      hr = OpenDataSource();
      if (FAILED(hr))
         return hr;
      __if_exists(GetRowsetProperties)
      {
         CDBPropSet propset(DBPROPSET_ROWSET);
         __if_exists(HasBookmark)
         {
            propset.AddProperty(DBPROP_IRowsetLocate, true);
         }
         GetRowsetProperties(&propset);
         return OpenRowset(&propset);
      }
      __if_not_exists(GetRowsetProperties)
      {
         __if_exists(HasBookmark)
         {
            CDBPropSet propset(DBPROPSET_ROWSET);
            propset.AddProperty(DBPROP_IRowsetLocate, true);
            return OpenRowset(&propset);
         }
      }
      return OpenRowset();
   }
   HRESULT OpenRowset(DBPROPSET *pPropSet = NULL)
   {
HRESULT hr = Open(m_session, "Authors", pPropSet);
#ifdef _DEBUG
      if(FAILED(hr))
         AtlTraceErrorRecords(hr);
#endif
      return hr;
   }
   void CloseAll()
   {
      Close();
      CloseDataSource();
   }
};

참고 항목

OLE DB 소비자 특성