Zjednodušení přístupu k datům s použitím atributů databáze
Toto téma ukazuje použití atributů databáze ke zjednodušení databázových operací.
Základním způsobem přístupu k informacím z databáze je vytvoření třídy příkazu (nebo tabulky) a třídy záznamů uživatele pro určitou tabulku v databázi. Atributy databáze zjednodušují některé deklarace šablony, které jste museli udělat dříve.
Pro předvedení použití atributů databáze jsou v následujících částech uvedeny dvě ekvivalentní deklarace třídy záznamů tabulky a uživatele: první používá atributy a druhý používá šablony OLE DB. Takový kód deklarace se obvykle umístí do souboru záhlaví pojmenovaného pro objekt tabulky nebo příkazu, například Authors.h.
Porovnáním těchto dvou souborů zjistíte, jak mnohem jednodušší je používat atributy. Mezi rozdíly patří:
Pomocí atributů je nutné deklarovat pouze jednu třídu:
CAuthors
, zatímco pomocí šablon musíte deklarovat dvě:CAuthorsNoAttrAccessor
aCAuthorsNoAttr
.Volání
db_source
v atributové verzi je ekvivalentníOpenDataSource()
volání v deklaraci šablony.Volání
db_table
v atributové verzi odpovídá následující deklaraci šablony:class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
Volání
db_column
v atributové verzi jsou ekvivalentní mapě sloupců (vizBEGIN_COLUMN_MAP ... END_COLUMN_MAP
) v deklaraci šablony.
Atributy za vás vloží deklaraci třídy záznamu uživatele. Třída záznamu uživatele je rovna CAuthorsNoAttrAccessor
v deklaraci šablony. Pokud je CAuthors
vaše třída tabulky , vložená třída záznamu uživatele má název CAuthorsAccessor
a můžete zobrazit pouze její deklaraci vložený kód. Další informace naleznete v části Třídy záznamů uživatele vložené atributem v záznamech uživatele.
V atributu i v kódu šablony je nutné nastavit vlastnosti sady řádků pomocí CDBPropSet::AddProperty
.
Informace o atributech probíraných v tomto tématu naleznete v tématu OLE DB Consumer Attributes.
Poznámka:
include
Následující příkazy jsou potřeba ke kompilaci následujících příkladů:
#include <atlbase.h> #include <atlplus.h> #include <atldbcli.h>
Deklarace tabulek a přístupových objektů pomocí atributů
Následující volání kódu db_source
a db_table
třídy tabulky. db_source
určuje zdroj dat a připojení, které se má použít. db_table
vloží příslušný kód šablony pro deklaraci třídy tabulky. db_column
zadejte mapu sloupce a injektujte deklaraci přístupového objektu. Atributy příjemce OLE DB můžete použít v libovolném projektu, který podporuje ATL.
Tady je deklarace tabulek a přístupových objektů pomocí atributů:
//////////////////////////////////////////////////////////////////////
// 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);
}
};
Deklarace tabulek a přístupových objektů pomocí šablon
Tady je deklarace tabulky a přístupového objektu pomocí šablon.
//////////////////////////////////////////////////////////////////////
// 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();
}
};