Vereinfachen des Datenzugriffs mit Datenbankattributen
In diesem Thema wird die Verwendung von Datenbankattributen veranschaulicht, um Datenbankvorgänge zu vereinfachen.
Die grundlegende Möglichkeit für den Zugriff auf Informationen aus einer Datenbank besteht darin, eine Befehlsklasse (oder eine Tabellenklasse) und eine Benutzerdatensatzklasse für eine bestimmte Tabelle in der Datenbank zu erstellen. Die Datenbankattribute vereinfachen einige der Vorlagendeklarationen, die Sie zuvor ausgeführt haben.
Um die Verwendung von Datenbankattributen zu veranschaulichen, zeigen die folgenden Abschnitte zwei gleichwertige Tabellen- und Benutzerdatensatzklassendeklarationen an: Die erste verwendet Attribute und die zweite verwendet OLE DB-Vorlagen. Dieser Deklarationscode wird in der Regel in einer Kopfzeilendatei platziert, die für die Tabelle oder das Befehlsobjekt benannt ist, z. B. Authors.h.
Indem Sie die beiden Dateien vergleichen, können Sie sehen, wie viel einfacher es ist, Attribute zu verwenden. Zu den Unterschieden gehören:
Mithilfe von Attributen müssen Sie nur eine Klasse deklarieren:
CAuthors
, während Sie mit Vorlagen zwei deklarieren müssen:CAuthorsNoAttrAccessor
undCAuthorsNoAttr
.Der
db_source
Aufruf in der attributten Version entspricht demOpenDataSource()
Aufruf in der Vorlagendeklaration.Der
db_table
Aufruf in der attributten Version entspricht der folgenden Vorlagendeklaration:class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
Die
db_column
Aufrufe in der attributten Version entsprechen der Spaltenzuordnung (sieheBEGIN_COLUMN_MAP ... END_COLUMN_MAP
) in der Vorlagendeklaration.
Mit den Attributen wird eine Benutzerdatensatzklassendeklaration für Sie eingefügt. Die Benutzerdatensatzklasse ist in der Vorlagendeklaration gleich CAuthorsNoAttrAccessor
. Wenn die Tabellenklasse lautet CAuthors
, wird die eingefügte Benutzerdatensatzklasse benannt CAuthorsAccessor
, und Sie können die Deklaration nur im eingefügten Code anzeigen. Weitere Informationen finden Sie unter "Attributinjizierte Benutzerdatensatzklassen" in Benutzerdatensätzen.
Sowohl im attributierten als auch im vorlagenbasierten Code müssen Sie rowset-Eigenschaften mithilfe von CDBPropSet::AddProperty
.
Informationen zu den in diesem Thema erläuterten Attributen finden Sie unter OLE DB Consumer Attributes.
Hinweis
Die folgenden include
Anweisungen sind erforderlich, um die folgenden Beispiele zu kompilieren:
#include <atlbase.h> #include <atlplus.h> #include <atldbcli.h>
Tabellen- und Accessordeklaration mithilfe von Attributen
Der folgende Code ruft und db_table
die Tabellenklasse aufdb_source
. db_source
Gibt die zu verwendende Datenquelle und Verbindung an. db_table
fügt den entsprechenden Vorlagencode ein, um eine Tabellenklasse zu deklarieren. db_column
geben Sie die Spaltenzuordnung an, und fügen Sie die Accessordeklaration ein. Sie können OLE DB-Consumerattribute in jedem Projekt verwenden, das ATL unterstützt.
Dies ist die Tabellen- und Accessordeklaration mit Attributen:
//////////////////////////////////////////////////////////////////////
// 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);
}
};
Tabellen- und Accessordeklaration mithilfe von Vorlagen
Hier sehen Sie die Tabellen- und Accessordeklaration mithilfe von Vorlagen.
//////////////////////////////////////////////////////////////////////
// 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();
}
};