|
|
最近我们公司开发有关电力方面的软件,分成了几个大模块,由于种种原因.大家所使用的开发工具比较杂,很是头痛,大家想了很多的办法,一直没能很好的解决这个问题!我们的开发工具有Microsoft Visual C++ 6.0,Microsoft Visual Basic ,Borland C++ Builder,一开始如果只用Microsoft 开发工具的话,可能会好解决一些,但是这样的情况不大好弄,如果让大家换工具,这样这个项目就会被耽误了!
一开始大家想做成普通的DLL来解决,可是由于Microsoft VC的DLL的格式与C++ Builder 格式不一样,它们进出栈的顺序也不一样,虽然也有方法解决这个问题,但似乎不怎么方便,最后决定核心的几个模块做成COM组件!由于我对VC比较熟悉吧,这几个核心组件由Me 来完成,下面我在这里谈谈有关用ATL 与STL,ADO 的组合使用.
ATL ,这个大家应用不陌生了吧,很多人都谈过,的确用它来写COM组件,很方便,但是对你的要求也要高一些,有困难,咱不怕,学习吗!特别用ATL写一些涉及GUI的ActiveX 控件,你就不能依靠MFC,当然你也可以用MFC ,如果这样大大削弱ATL的优势!没有了MFC中CTypedPtrList,CObList,我怎么处理大量的数据,而且我写的是处理数据库的呀,这样STL 的优势就可以展示,STL一开始学起来不太容易,但是你能熟练的用它时,我猜你会放弃用什么CTypedPtrList,CObList,CArray了,因为STL的功能太强大了的呀!
另外写数据库的组件,你可以用很多的方式,但是我比较喜欢用ADO,原因是一方面基于COM,处理速率比较快,还有一个主要原因用起来很灵活,也很简单的呀!
废话说了这么多,下面说一下我的代码:
这个COM组件主要提供了一些接口连接各种数据库如常见的Access,SQL Server,Oracle 也可以是ODBC数据源,你可以调用一个方法,并提供一些参数可以连接上数据库了,连接以后你可以直接执行SQL语句,也可以设置是否需要事务处理,以及查询数据库中有哪些表以及表中哪些字段,你也可以获得数据等等,大家看了代码就知道了,由于时间原因,更多功能我没有写来!
代码中注释还有一些,有些地方可能不太理解,如下面:
//-------------------------------------
//By the row and col to get the value.
//Parameter:nRow ,nCol .the start row and col is 0 ,not 1.
STDMETHODIMP CDBInterface::GetRecordValue(int nRow, int nCol, OLECHAR *pValue)
{
USES_CONVERSION;
//Verify the nRow can’t greater than max record
//the nCol can’t greater than number of the field
int nRowCount,nColCount;
int nHasRead=0;
HRESULT hr;
string strTemp;
RecordIter iter;
RecordValue list;
nHasRead=GetTwentyRecord(m_pRst);
hr=GetRecordCount(&nRowCount);
if (FAILED(hr))
return E_FAIL;
hr=GetFieldCount(&nColCount);
if (FAILED(hr))
return E_FAIL;
if (nRow>=nRowCount || nCol>=nColCount)
return E_FAIL;
//When the row is less than MAX_RECORD ,we get the record directly from the memory
//that we have store,or else we read record from database until we have read greater
//or equal the query row.
if (nRow<MAX_RECORD)
{
list=m_RecordValue[nRow];
iter=list.begin();
for(int i=0;i<=nCol && iter!=list.end();i++)
{
iter++;
}
if (iter!=list.end())
{
strTemp=*iter;
wcscpy(pValue,T2OLE(strTemp.c_str()));
}
else
*pValue=L’0’;
}
else
{
int nTemp=0;
while(nHasRead<=nRow)
{
nTemp=GetTwentyRecord(m_pRst);
if (nTemp==0)
{
*pValue=L’0’;
return E_FAIL;
}
else
nHasRead+=nTemp;
}
//Find which row we need
int nRowTemp=nRow%MAX_RECORD;
list=m_RecordValue[nRowTemp];
iter=list.begin();
for(int i=0;i<=nCol && iter!=list.end();i++)
{
iter++;
}
if (iter!=list.end())
{
strTemp=*iter;
wcscpy(pValue,T2OLE(strTemp.c_str()));
}
else
{
*pValue=L’0’;
}
}
//If we has compelete one query ,then make sure the record pointer to the
//first ,so that promise the next query.
m_pRst->MoveFirst();
return S_OK;
}
//-------------------------------------
//Considering too many record will cost too many memeory
//There ,we only store twenty record ,
//Before ,we stroe the next record ,first ,we must clear the vector and list
//Return Value:The record number that we have actually read
int CDBInterface::GetTwentyRecord(_RecordsetPtr pRst)
{
if (!m_bExecuted)
return 0;
//clear pervious record
RecordValue list;
string strValue;
for (int i=0;i<m_RecordValue.size();i++)
{
list=m_RecordValue;
list.clear();
}
m_RecordValue.clear();
int nHasStore=0;
_variant_t varValue;
_bstr_t bstrValue;
FieldPtr fieldCtl;
while (!pRst->EndofFile && nHasStore++<MAX_RECORD)
{
list.clear();
fieldCtl=pRst->Fields->GetItem(long(0));
varValue=fieldCtl->Value;
if (varValue.vt==VT_NULL)
{
bstrValue="";
}
else
{
bstrValue=varValue;
}
strValue=(char *)bstrValue;
list.push_back(strValue);
//Get each field value and then push to the list
//After get all the field value, push the vector
for (int j=1;j<pRst->Fields->Count;j++)
{
fieldCtl=pRst->Fields->GetItem(long(j));
varValue=fieldCtl->Value;
//If this field is NULL,we must set it NULL,
//or else ,maybe runtime error!
if (varValue.vt==VT_NULL)
{
bstrValue="";
}
else
{
bstrValue=varValue;
}
strValue=(char*)bstrValue;
list.push_back(strValue);
}
m_RecordValue.push_back(list);
pRst->MoveNext();
}
return nHasStore;
}
一些变量大家看了代码就知道,上面我考虑到使用内存和速度问题,大家只要更改一下MAX_RECORD就可以,我的意思是当用户调用这个方法,我先从database中读MAX_RECORD存入到内存中,如果要Query 在内存中,可以直接返回,否则每次从数据库中读出MAX_RECORD,大家还要注意的就是STL在这其中的运用,我也是个初学者,大家互相学习吗!
|
|