Simplificando o acesso a dados com atributos de banco de dados
Este tópico demonstra o uso de atributos de banco de dados para simplificar as operações de banco de dados.
A forma básica de acessar informações de um banco de dados é criar uma classe de comando (ou tabela) e uma classe de registro de usuário para uma determinada tabela no banco de dados. Os atributos do banco de dados simplificam a algumas das declarações do modelo que você anteriormente tinha de fazer.
Para demonstrar o uso de atributos de banco de dados, as seções a seguir mostram dois tabela equivalente e declarações de classe do registro do usuário: o primeiro usa atributos e a segunda usa modelos OLE DB. Esse código de declaração é geralmente colocado em um arquivo de cabeçalho chamado para o objeto de tabela ou de comando, por exemplo, Authors.h.
Comparando dois arquivos, você pode ver como é simples é usar atributos. Entre as diferenças são:
Usando atributos, você só precisará declarar uma classe: CAuthors, enquanto com modelos você precisa declarar dois: CAuthorsNoAttrAccessor and CAuthorsNoAttr.
O db_source chamada na versão atribuída é equivalente a OpenDataSource() chamar na declaração do modelo.
O db_table chamada na versão atribuída é equivalente a seguinte declaração de modelo:
class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor> >
O db_column chamadas na versão atribuída são equivalentes do mapa de coluna (consulte BEGIN_COLUMN_MAP ... END_COLUMN_MAP) na declaração do modelo.
Os atributos de injetar uma declaração de classe do registro de usuário para você. A classe de registro de usuário é equivalente a CAuthorsNoAttrAccessor na declaração do modelo. Se sua classe de tabela é CAuthors, a classe de registro de usuário injetado é nomeada CAuthorsAccessor, e você só pode exibir sua declaração no código injetado. Para obter mais informações, consulte "Classes de registro de usuário do Attribute-Injected" em registros de usuário.
Observe que o atribuída tanto o código de modelo, você deve definir propriedades de conjunto de linhas usando CDBPropSet::AddProperty.
Para obter informações sobre os atributos discutidos neste tópico, consulte OLE DB consumidor atributos.
Tabela e a declaração de assessor usando atributos
O seguinte código chama db_source e db_table na classe de tabela. db_sourceEspecifica a fonte de dados e a conexão a ser usada. db_table injeta o código de modelo apropriado para declarar uma classe de tabela. db_column especificar o mapa de coluna e injetar a declaração do acessador. Você pode usar atributos de consumidor do OLE DB em qualquer projeto que ofereça suporte ATL.
Aqui está a declaração de tabela e assessor usando atributos:
//////////////////////////////////////////////////////////////////////
// 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:
DWORD m_dwAuIDStatus;
DWORD m_dwAuthorStatus;
DWORD m_dwYearBornStatus;
DWORD m_dwAuIDLength;
DWORD m_dwAuthorLength;
DWORD 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);
}
};
Tabela e a declaração de assessor usando modelos
Aqui está a declaração de tabela e assessor usando modelos.
//////////////////////////////////////////////////////////////////////
// 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();
}
};