소비자 마법사 생성 클래스
ATL OLE DB 소비자 마법사를 사용하여 소비자를 생성할 때 OLE DB 템플릿이나 OLE DB 특성을 사용할 수 있습니다.두 경우 모두 마법사는 명령 클래스 및 사용자 레코드 클래스를 생성합니다.명령 클래스에는 마법사에서 지정한 데이터 소스와 행 집합을 여는 코드가 들어 있습니다.사용자 레코드 클래스에는 선택한 데이터베이스 테이블의 열 매핑이 들어 있습니다.그러나 두 경우에 생성된 코드는 서로 다릅니다.
템플릿 기반 소비자를 선택하면 마법사는 명령 클래스 및 사용자 레코드 클래스를 생성합니다.명령 클래스 이름은 마법사의 클래스 상자에 입력한 이름이며(예: CProducts) 사용자 레코드 클래스 이름은 "ClassNameAccessor" 폼의 이름입니다(예: CProductsAccessor).두 클래스 모두 소비자 헤더 파일에 있습니다.
특성을 사용하는 소비자를 선택하면 사용자 레코드 클래스는 "_ClassNameAccessor" 형식의 이름으로 삽입됩니다.즉, 텍스트 편집기의 명령 클래스만 볼 수 있으며, 사용자 레코드 클래스는 삽입된 코드로만 볼 수 있습니다.삽입된 코드를 보는 방법은 삽입한 코드 디버깅을 참조하십시오.
다음 예제에서는 Northwind 데이터베이스의 Products 테이블에 작성된 명령 클래스를 사용하여 명령 클래스 및 사용자 레코드 클래스에 대한 마법사 생성 소비자 코드를 보여 줍니다.
템플릿 기반 사용자 레코드 클래스
OLE DB 특성이 아니라 OLE DB 템플릿을 사용하여 OLE DB 소비자를 만들면 이 단원에서 설명하는 것처럼 마법사가 코드를 생성합니다.
열 데이터 멤버
사용자 레코드 클래스의 첫 번째 부분에는 데이터 바인딩된 각 열에 대한 상태 및 길이 데이터 멤버와 데이터 멤버 선언이 포함됩니다.이러한 데이터 멤버에 대한 자세한 내용은 마법사 생성 접근자의 필드 상태 데이터 멤버를 참조하십시오.
[!참고]
사용자 레코드 클래스를 수정하거나 사용자 고유의 소비자를 작성하는 경우, 데이터 변수가 상태 변수와 길이 변수보다 앞에 있어야 합니다.
[!참고]
ATL OLE DB 소비자 마법사는 DB_NUMERIC 형식을 사용하여 숫자 데이터 형식을 바인딩합니다.예전에 이 마법사에서는 DBTYPE_VARNUMERIC(DB_VARNUMERIC 형식에 의해 설명되는 형식, Oledb.h 참조)을 사용했었습니다.소비자를 만드는 데 마법사를 사용하지 않는 경우에는 DB_NUMERIC을 사용하는 것이 좋습니다.
// Products.H : Declaration of the CProducts class
class CProductsAccessor
{
public:
// Column data members:
LONG m_ProductID;
TCHAR m_ProductName[41];
LONG m_SupplierID;
LONG m_CategoryID;
TCHAR m_QuantityPerUnit[21];
CURRENCY m_UnitPrice;
SHORT m_UnitsInStock;
SHORT m_UnitsOnOrder;
SHORT m_ReorderLevel;
VARIANT_BOOL m_Discontinued;
// Column status data members:
DBSTATUS m_dwProductIDStatus;
DBSTATUS m_dwProductNameStatus;
DBSTATUS m_dwSupplierIDStatus;
DBSTATUS m_dwCategoryIDStatus;
DBSTATUS m_dwQuantityPerUnitStatus;
DBSTATUS m_dwUnitPriceStatus;
DBSTATUS m_dwUnitsInStockStatus;
DBSTATUS m_dwUnitsOnOrderStatus;
DBSTATUS m_dwReorderLevelStatus;
DBSTATUS m_dwDiscontinuedStatus;
// Column length data members:
DBLENGTH m_dwProductIDLength;
DBLENGTH m_dwProductNameLength;
DBLENGTH m_dwSupplierIDLength;
DBLENGTH m_dwCategoryIDLength;
DBLENGTH m_dwQuantityPerUnitLength;
DBLENGTH m_dwUnitPriceLength;
DBLENGTH m_dwUnitsInStockLength;
DBLENGTH m_dwUnitsOnOrderLength;
DBLENGTH m_dwReorderLevelLength;
DBLENGTH m_dwDiscontinuedLength;
행 집합 속성
다음으로 마법사는 행 집합 속성을 설정합니다.ATL OLE DB 소비자 마법사에서 Change, Insert, 또는 Delete를 선택하면, 적절할 속성이 여기에 설정됩니다. DBPROP_IRowsetChange는 언제나 설정되며 하나 이상의 DBPROPVAL_UP_CHANGE, DBPROPVAL_UP_INSERT, 및/또는 DBPROPVAL_UP_DELETE가 각각 설정됩니다.
void GetRowsetProperties(CDBPropSet* pPropSet)
{
pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
pPropSet->AddProperty(DBPROP_IRowsetChange, true, DBPROPOPTIONS_OPTIONAL);
pPropSet->AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);
}
명령 또는 테이블 클래스
명령 클래스를 지정하면 마법사는 명령 클래스를 선언합니다. 예를 들어 템플릿 기반 코드의 경우 명령은 다음과 같이 나타납니다.
DEFINE_COMMAND_EX(CProductsAccessor, L" \
SELECT \
ProductID, \
ProductName, \
SupplierID, \
CategoryID, \
QuantityPerUnit, \
UnitPrice, \
UnitsInStock, \
UnitsOnOrder, \
ReorderLevel, \
Discontinued \
FROM dbo.Products")
열 맵
이제 마법사는 열 바인딩 또는 열 맵을 생성합니다.여러 공급자를 사용하여 몇 가지 문제를 해결하기 위해, 다음 코드에서는 공급자가 보고한 순서와는 다른 순서로 열을 바인딩합니다.
BEGIN_COLUMN_MAP(CProductsAccessor)
COLUMN_ENTRY_LENGTH_STATUS(1, m_ProductID, m_dwProductIDLength, m_dwProductIDStatus)
COLUMN_ENTRY_LENGTH_STATUS(2, m_ProductName, m_dwProductNameLength, m_dwProductNameStatus)
COLUMN_ENTRY_LENGTH_STATUS(3, m_SupplierID, m_dwSupplierIDLength, m_dwSupplierIDStatus)
COLUMN_ENTRY_LENGTH_STATUS(4, m_CategoryID, m_dwCategoryIDLength, m_dwCategoryIDStatus)
COLUMN_ENTRY_LENGTH_STATUS(5, m_QuantityPerUnit, m_dwQuantityPerUnitLength, m_dwQuantityPerUnitStatus)
_COLUMN_ENTRY_CODE(6, DBTYPE_CY, _SIZE_TYPE(m_UnitPrice), 0, 0, offsetbuf(m_UnitPrice), offsetbuf(m_dwUnitPriceLength), offsetbuf(m_dwUnitPriceStatus))
COLUMN_ENTRY_LENGTH_STATUS(7, m_UnitsInStock, m_dwUnitsInStockLength, m_dwUnitsInStockStatus)
COLUMN_ENTRY_LENGTH_STATUS(8, m_UnitsOnOrder, m_dwUnitsOnOrderLength, m_dwUnitsOnOrderStatus)
COLUMN_ENTRY_LENGTH_STATUS(9, m_ReorderLevel, m_dwReorderLevelLength, m_dwReorderLevelStatus)
_COLUMN_ENTRY_CODE(10, DBTYPE_BOOL, _SIZE_TYPE(m_Discontinued), 0, 0, offsetbuf(m_Discontinued), offsetbuf(m_dwDiscontinuedLength), offsetbuf(m_dwDiscontinuedStatus))
END_COLUMN_MAP()
};
클래스 선언
마지막으로 마법사에서는 다음과 같은 명령 클래스 선언을 생성합니다.
class CProducts : public CCommand<CAccessor<CProductsAccessor> >
특성 삽입 사용자 레코드 클래스
데이터베이스 특성(db_command 또는 db_table)을 사용하여 OLE DB 소비자를 만드는 경우, 특성은 "_ClassNameAccessor" 형태의 이름을 가진 사용자 레코드 클래스를 만듭니다. 예를 들어, 명령 클래스의 이름을 COrders라고 정하면 사용자 레코드 클래스는 _COrdersAccessor가 됩니다.사용자 레코드 클래스가 클래스 뷰에 나타나지만, 사용자 레코드 클래스를 두 번 클릭하면 헤더 파일의 명령이나 테이블 클래스를 대신 탐색합니다.이러한 경우에는 특성 삽입 코드를 봄으로써 사용자 레코드 클래스의 실제 선언만을 볼 수 있습니다.
특성 사용 소비자에서 메서드를 추가하거나 재정의하는 경우에는 문제가 발생할 수 있습니다.예를 들어, _COrdersAccessor 생성자를 COrders 선언에 추가할 수 있지만 실제로 이 경우 생성자는 삽입된 COrdersAccessor 클래스에 추가됩니다.이 생성자가 열/매개 변수를 초기화할 수는 있지만, COrdersAccessor 개체를 직접 초기화할 수는 없으므로 이런 식으로 복사 생성자를 만들 수 없습니다.COrders 클래스에서 직접 생성자(또는 다른 메서드)가 필요하면 COrders에서 파생된 새 클래스를 정의하고 여기에 필요한 메서드를 추가하는 것이 좋습니다.
다음 예제에서 마법사는 COrders 클래스에 대한 선언을 생성하지만 특성이 사용자 레코드 클래스 COrdersAccessor를 삽입하므로 이 사용자 레코드 클래스가 나타나지 않습니다.
#define _ATL_ATTRIBUTES
#include <atlbase.h>
#include <atldbcli.h>
[
db_source(L"your connection string"),
db_command(L"Select ShipName from Orders;")
]
class COrders
{
public:
// COrders() // incorrect constructor name
_COrdersAccessor() // correct constructor name
{
}
[db_column(1) ] TCHAR m_ShipName[41];
};
삽입된 명령 클래스 선언은 다음과 같이 나타납니다.
class CProducts : public CCommand<CAccessor<_CProductsAccessor> >
삽입된 코드 대부분은 템플릿 버전과 동일하거나 비슷합니다.삽입된 메서드의 주요 차이점에 대한 설명은 소비자 마법사 생성 메서드에 나와 있습니다.
삽입된 코드를 보는 방법은 삽입한 코드 디버깅을 참조하십시오.