我在几年前曾经用delphi写过一个数据库封装的源代码,在我的资源里有下载
http://d.download.csdn.net/down/165474/zyx040404
最近需要写一个ERP的软件,自己闲来无事,就花了2周时间改写了delphi的代码,使用MS.NET 2003实现了一下
在使用MS.NET 2003实现的过程中也发现了原来程序的一些bug
如果你有兴趣,也可以参考一下---------- 说明 ----------
1. 该代码可以免费使用, 该代码的名字定为"哲别"
2. 如果你需要使用该代码, 请注明该代码的原来作者: Jacky Zhou
3. 如果你发现该代码有bug,可以自己修改或者请给我发email: [email protected]
4. 该数据库封装代码功能可以对数据库的表,视图和存储过程进行封装,易于系统移植,扩展,使用了interface,factory等方法
5. 实现了主从表的操作(delphi的代码没有实现)我会慢慢介绍源代码的原理
http://d.download.csdn.net/down/165474/zyx040404
最近需要写一个ERP的软件,自己闲来无事,就花了2周时间改写了delphi的代码,使用MS.NET 2003实现了一下
在使用MS.NET 2003实现的过程中也发现了原来程序的一些bug
如果你有兴趣,也可以参考一下---------- 说明 ----------
1. 该代码可以免费使用, 该代码的名字定为"哲别"
2. 如果你需要使用该代码, 请注明该代码的原来作者: Jacky Zhou
3. 如果你发现该代码有bug,可以自己修改或者请给我发email: [email protected]
4. 该数据库封装代码功能可以对数据库的表,视图和存储过程进行封装,易于系统移植,扩展,使用了interface,factory等方法
5. 实现了主从表的操作(delphi的代码没有实现)我会慢慢介绍源代码的原理
数据库封装(Database Gateway,简称DBGW)主要是含有
interface IDBGW :是操作数据库的主要代码,insert,delete,update等
interface IEntity : 对应的是一个记录,我们称之为实体类
interface IEntityList : 是IEntity的一个集合
interface IFactory :class factory,在DBGW中会用到
CEntityCondition :附件条件,比如delete时的条件
CEntityRule :暂时未用还有一些数据定义
enum EntityLoadType
{
eLoadTypeTable,
eLoadTypeView,
eLoadTypeStoragedProc
};struct tagField
{
TSTRING name;
int type;
int length;
BOOL is_pk;
};
typedef vector<tagField> VECFIELDS;
typedef VECFIELDS::iterator VECFIELDS_IT;
typedef VECFIELDS::const_iterator VECFIELDS_CONST_IT;
Entity的接口文件,主要是用来保存一个记录的值,主要是Get/Set方法,每个
在实现的时候,需要自己创建不同的实体类,比如对应一个表创建一个Entity类,每个实体类都有自己不同的名字,该名字会在class factory中使用到#pragma once#include <comutil.h>
#include "../../SAMA/SAMADataDefine.h"
#include "../../SAMA/SAMA.h"
#include "DBGWDataDefine.h"class IEntity
{
public:
virtual TSTRING GetEntityName() = 0; virtual _variant_t * GetAttributeValue(const TSTRING & strAttributeName, _variant_t & var) = 0;
virtual void SetAttributeValue(const TSTRING & strAttributeName, const _variant_t & var) = 0;
virtual BOOL IsAttributeChanged(const TSTRING & strFieldName) = 0;
virtual void SetChangedFlag(BOOL bFlag) = 0;
virtual void ClearValue() = 0;
virtual BOOL IsValueCleared() = 0;protected:
BOOL m_bIsValueCleared;
};typedef IEntity * PIEntity;
就是Entity的一个集合,目前是使用vetor实现的,主要方法是Add、Remove、Get Entity#pragma once#include "IEntity.h"typedef vector<PIEntity> VECENTITY;
typedef VECENTITY::iterator VECENTITY_IT;
typedef VECENTITY::const_iterator VECENTITY_CONST_IT;class IEntityList
{
public:
virtual void Release() = 0; virtual TSTRING GetEntityName() = 0;
virtual void SetEntityName(const TSTRING & sEntityName) = 0; virtual int GetEntityCount() = 0; virtual void AddEntity(PIEntity pety) = 0;
virtual void RemoveEntity(int nIndex) = 0;
virtual PIEntity GetEntity(int nIndex) = 0; virtual void Clear() = 0;protected:
VECENTITY m_list;
TSTRING m_sEntityName;protected:
BOOL m_bIsValueCleared;
};typedef IEntityList * PIEntityList;
主要是通过Entity的名字得到对应的表名,表的字段,以及Entity的实例#pragma once
#include "IEntity.h"class IEntityFactory
{
public:
virtual int GetLoadType(const TSTRING & sEntityName) = 0;
virtual TSTRING GetTableName(const TSTRING & sEntityName) = 0;
virtual VECFIELDS * CreateEntityFields(const TSTRING & sEntityName) = 0;
virtual PIEntity CreateEntity(const TSTRING & sEntityName) = 0;
};typedef IEntityFactory * PIEntityFactory;
这是数据库封装的接口代码,主要方法是
LoadEntity :从数据库中得到一个记录,传入的参数是Entity,Entity必须先赋上表的关键字段的值,DBGW会通过关键字段找到该记录,然后再赋值给Entity
LoadEntityList : 从数据库中得到一个记录的集合
InsertEntity :向数据库中插入一条记录
UpdateEntity :修改数据库中的一条记录
DeleteEntity : 删除数据库中的一条记录
以上三个函数的参数Entity都必须先赋上关键字段的值
InsertMasterDetail、DeleteMasterDetail是对主从表的操作#pragma once#include "../SAMADataDefine.h"
#include "./IEntityFactory.h"
#include "./IEntityList.h"struct IDBGW
{
virtual void Initialize(const PIEntityFactory pFactory) = 0;
virtual void Release() = 0; virtual COMMON_ERR Open(const TSTRING & sConnectionString) = 0;
virtual void Close() = 0; virtual void SetEntityFactory(const PIEntityFactory pFactory) = 0; virtual COMMON_ERR LoadEntity(PIEntity pety, const PIEntityList listCondition = NULL) = 0;
virtual COMMON_ERR LoadEntityList(PIEntityList list, const PIEntityList listCondition = NULL, const PIEntityList listRule = NULL) = 0;
virtual COMMON_ERR InsertEntity(const PIEntity pety) = 0;
virtual COMMON_ERR UpdateEntity(const PIEntity pety, const PIEntityList listCondition = NULL) = 0;
virtual COMMON_ERR DeleteEntity(const PIEntity pety, const PIEntityList listCondition = NULL) = 0; virtual COMMON_ERR InsertMasterDetail(const PIEntity master, PIEntityList detail) = 0;
virtual COMMON_ERR DeleteMasterDetail(const PIEntity master, PIEntityList detail) = 0; virtual void Refresh(PIEntityList list) = 0;
};
IDGBW接口的实现头文件
成员变量
PIEntityFactory m_pIEntityFactory 接口定义
_ConnectionPtr m_pConnection ADO的connection类#pragma once#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "ADOEOF")#include <oledb.h>
#include <stdio.h>
#include <conio.h>
#include "icrsint.h"
#include "IDBGW.h"class CDBGWImpl : public IDBGW
{
public:
CDBGWImpl(void);
virtual ~CDBGWImpl(void); virtual void Initialize(const PIEntityFactory pFactory);
virtual void Release(); virtual COMMON_ERR Open(const TSTRING & sConnectionString);
virtual void Close(); virtual void SetEntityFactory(const PIEntityFactory pFactory); virtual COMMON_ERR LoadEntity(PIEntity pety, const PIEntityList listCondition = NULL);
virtual COMMON_ERR LoadEntityList(PIEntityList list, const PIEntityList listCondition = NULL, const PIEntityList listRule = NULL);
virtual COMMON_ERR InsertEntity(const PIEntity pety);
virtual COMMON_ERR UpdateEntity(const PIEntity pety, const PIEntityList listCondition = NULL);
virtual COMMON_ERR DeleteEntity(const PIEntity pety, const PIEntityList listCondition = NULL); virtual COMMON_ERR InsertMasterDetail(const PIEntity master, PIEntityList detail);
virtual COMMON_ERR DeleteMasterDetail(const PIEntity master, PIEntityList detail); virtual void Refresh(PIEntityList list);private:
PIEntityFactory m_pIEntityFactory; COMMON_ERR __LoadEntityByTable(PIEntity pety, const PIEntityList listCondition);
virtual COMMON_ERR __LoadEntityByStoragedProc(PIEntity pety, const PIEntityList listCondition); int __GetTableFieldType(const VECFIELDS * pvecFields, const TSTRING & sTableFieldName); TSTRING __GetCondition(const TSTRING & sEntityName, const PIEntityList listCondition);
TSTRING __GetRule(const TSTRING & sEntityName, const PIEntityList listRule);
TSTRING __GetPKCondition(const PIEntity pety);public:
_ConnectionPtr m_pConnection;};
这是DBGW主要的实现文件,所有函数都在里面
先介绍几个简单的函数,
数据库的Open/Close#include "../StdAfx.h"
#include ".\dbgwimpl.h"
#include "DBGWErrorCode.h"const int MAX_DB_CONNECTION = 10;#define ID_AND _T(" AND ")const int AND_LENGTH = 5;CDBGWImpl::CDBGWImpl(void)
{
m_pIEntityFactory = NULL;
m_pConnection = NULL; ::CoInitialize(NULL);
}CDBGWImpl::~CDBGWImpl(void)
{
::CoUninitialize();
}void CDBGWImpl::Initialize(const PIEntityFactory pFactory)
{
m_pIEntityFactory = pFactory;
}void CDBGWImpl::Release()
{
delete this;
}COMMON_ERR CDBGWImpl::Open(const TSTRING & sConnectionString)
{
COMMON_ERR nError = COMMON_OK; try
{
// open connection and record set
m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection->Open(_bstr_t(sConnectionString.c_str()), _T(""), _T(""), adConnectUnspecified);
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CONNECT_DB_FAILED;
} return nError;
}void CDBGWImpl::Close()
{
m_pConnection->Close();
}void CDBGWImpl::SetEntityFactory(const PIEntityFactory pFactory)
{
m_pIEntityFactory = pFactory;
}
函数:LoadEntityCOMMON_ERR CDBGWImpl::LoadEntity(PIEntity pety, const PIEntityList listCondition /* = NULL */)
{
COMMON_ERR nError = COMMON_OK; //通过factory得到entity对应的type
int nLoadType = m_pIEntityFactory->GetLoadType(pety->GetEntityName());
switch(nLoadType)
{
case eLoadTypeStoragedProc:
nError = __LoadEntityByStoragedProc(pety, listCondition);
break;
case eLoadTypeTable:
case eLoadTypeView:
default:
nError = __LoadEntityByTable(pety, listCondition);
break;
} return nError;
}COMMON_ERR CDBGWImpl::__LoadEntityByTable(PIEntity pety, const PIEntityList listCondition)
{
COMMON_ERR nError = COMMON_OK; _RecordsetPtr pRecordset = NULL; try
{
//get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(pety->GetEntityName());
if (sTableName.empty())
throw -1; //get table field
//通过factory得到entity对应的table fields
VECFIELDS * pvecFields = m_pIEntityFactory->CreateEntityFields(pety->GetEntityName()); //set SQL's title
TSTRING strSQLFields;
for (VECFIELDS_IT it = pvecFields->begin(); it != pvecFields->end(); ++it)
{
tagField & stuField = *it; strSQLFields = strSQLFields + _T("[") + sTableName + _T("].[") + stuField.name + _T("], ");
} //get rid of the last ',' in strSQLFields
strSQLFields = strSQLFields.substr(0, strSQLFields.size() - 2); //get where
TSTRING strSQLWhere;
if (listCondition && listCondition->GetEntityCount() > 0)
strSQLWhere = __GetCondition(pety->GetEntityName(), listCondition);
else //if listCondition = nil then only load this pety by pk
strSQLWhere = __GetPKCondition(pety); //it must have strSQLWhere
if (strSQLWhere.empty())
throw -1; //set SQL
TSTRING strSQL = _T("SELECT ");
strSQL = strSQL + strSQLFields + _T(" FROM ") + sTableName + _T(" WHERE ") + strSQLWhere; //run sql
HRESULT hTRes = pRecordset.CreateInstance(__uuidof(Recordset));
if (!SUCCEEDED(hTRes))
throw -1; hTRes = pRecordset->Open(strSQL.c_str(), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockPessimistic, adCmdText);
if (!SUCCEEDED(hTRes))
throw -1; if (pRecordset->ADOEOF)
throw -2; //the result must only be one record
//ADO_LONGPTR nCount = 0;
//int n = pRecordset->get_RecordCount(&nCount);
//if (nCount != 1)
// throw -1; //save the data to entity
int nFieldType;
_variant_t vIndex;
for (short i = 0; i < pRecordset->Fields->Count; ++i)
{
vIndex = i;
FieldPtr pFld = pRecordset->Fields->GetItem(&vIndex); _variant_t varFieldValue = pFld->GetValue();
if (VT_NULL == varFieldValue.vt)
continue; TSTRING strFieldName = pFld->GetName();
pety->SetAttributeValue(strFieldName, varFieldValue);
} pRecordset->Close();
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CANNOT_EXE_SQLSTMT;
} return nError;
}COMMON_ERR CDBGWImpl::__LoadEntityByStoragedProc(PIEntity pety, const PIEntityList listCondition)
{
//暂时没有实现
COMMON_ERR nError = COMMON_OK; return nError;
}
通过Entity的表名,字段名和关键字段的值作为查询条件得到唯一一个记录
DBGW其实就是通过一种映射把class程序映射成数据库操作,从而起到封装的作用
对于外部应用程序是不需要了解数据库的具体操作,适合多人合作开发程序
有人可以专门负责数据库,有人可以专门负责UI的设计,还有再做中间的商务逻辑
函数:____GetCondition(const TSTRING & sEntityName, const PIEntityList listCondition)
通过listCondition得到条件语句TSTRING CDBGWImpl::__GetCondition(const TSTRING & sEntityName, const PIEntityList listCondition)
{
TSTRING strSQLWhere; try
{
if (!listCondition)
throw -1; //get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(sEntityName);
if (sTableName.empty())
throw -1; for (int i = 0; i < listCondition->GetEntityCount(); ++i)
{
PIEntity etyCondition = listCondition->GetEntity(i); _variant_t var;
_variant_t varInt; //get table field name
TSTRING sTableFieldName = GetStringFromVariant(etyCondition->GetAttributeValue(ID_FIELD_NAME, var)); //get field type
etyCondition->GetAttributeValue(ID_FIELD_TYPE, varInt);
int nTableFieldType = varInt.intVal; //get operation
TSTRING strOperation = GetStringFromVariant(etyCondition->GetAttributeValue(ID_OPERATION, var)); //get field value
TSTRING strValue = GetStringFromVariant(etyCondition->GetAttributeValue(ID_VALUE, var)); //if field type is VT_BSTR or VT_DATE, strValue需要加两个'
if (VT_BSTR == nTableFieldType || VT_DATE == nTableFieldType)
strSQLWhere = strSQLWhere + _T("[") + sTableName + _T("].[") + sTableFieldName + _T("]") + strOperation + _T("'") + strValue + _T("'") + ID_AND;
else
strSQLWhere = strSQLWhere + _T("[") + sTableName + _T("].[") + sTableFieldName + _T("]") + strOperation + strValue + ID_AND;
} //get rid of the last ID_AND in strSQLWhere
strSQLWhere = strSQLWhere.substr(0, strSQLWhere.size() - AND_LENGTH);
}
catch (COMMON_ERR & err)
{
strSQLWhere = _T("");
}
catch(...)
{
strSQLWhere = _T("");
} return strSQLWhere;
}
GetStringFromVariant等有些函数还没有上传,在最新的SAMA代码里
函数:__GetPKCondition(const PIEntity pety)
通过entity的关键字段值得到的条件语句TSTRING CDBGWImpl::__GetPKCondition(const PIEntity pety)
{
TSTRING strCondition; try
{
//get Table Field
//通过factory得到entity对应的table fields
VECFIELDS * pvecFields = m_pIEntityFactory->CreateEntityFields(pety->GetEntityName()); for (VECFIELDS_IT it = pvecFields->begin(); it != pvecFields->end(); ++it)
{
tagField & stuField = *it; //如果该字段是关键字段
if (stuField.is_pk)
{
_variant_t var; //get value
TSTRING sFieldValue = GetStringFromVariant(pety->GetAttributeValue(stuField.name, var));
//if pk is '', then we can not get pk
if (sFieldValue.empty())
throw -1; //if field type is VT_BSTR or VT_DATE, sValue需要加两个'
if (VT_BSTR == stuField.type || VT_DATE == stuField.type)
strCondition = strCondition + stuField.name + _T("= '") + sFieldValue + _T("'") + ID_AND;
else
strCondition = strCondition + stuField.name + _T("=") + sFieldValue + ID_AND;
}
} //get rid of the last ID_AND in strCondition
strCondition = strCondition.substr(0, strCondition.size() - AND_LENGTH);
}
catch (COMMON_ERR & err)
{
strCondition = _T("");
}
catch(...)
{
strCondition = _T("");
} return strCondition;
}
函数:LoadEntityList(PIEntityList list, const PIEntityList listCondition /* = NULL */, const PIEntityList listRule /* = NULL */)
得到一个entity的集合,entitylist也有一个entity name和entity一样,通过factory得到表名等,组成一个Select语句COMMON_ERR CDBGWImpl::LoadEntityList(PIEntityList list, const PIEntityList listCondition /* = NULL */, const PIEntityList listRule /* = NULL */)
{
COMMON_ERR nError = COMMON_OK; _RecordsetPtr pRecordset = NULL; try
{
if (!list)
throw -1; list->Clear(); //get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(list->GetEntityName());
if (sTableName.empty())
throw -1; //get table field
//通过factory得到entity对应的table fields
VECFIELDS * pvecFields = m_pIEntityFactory->CreateEntityFields(list->GetEntityName());
TSTRING strSQLFields;
for (VECFIELDS_IT it = pvecFields->begin(); it != pvecFields->end(); ++it)
{
tagField & stuField = *it; strSQLFields = strSQLFields + _T("[") + sTableName + _T("].[") + stuField.name + _T("], ");
} //get rid of the last ',' in strSQLFields and strSQLValues
strSQLFields = strSQLFields.substr(0, strSQLFields.size() - 2); //get where
TSTRING sSQLWhere;
if (listCondition && listCondition->GetEntityCount() > 0)
sSQLWhere = __GetCondition(list->GetEntityName(), listCondition); //get rule
TSTRING strSQLRule;
if (listRule && listRule->GetEntityCount() > 0)
strSQLRule = __GetRule(list->GetEntityName(), listRule); //set SQL
TSTRING strSQL = _T("SELECT ");
if (sSQLWhere.empty())
strSQL = strSQL + strSQLFields + _T(" FROM ") + sTableName;
else
strSQL = strSQL + strSQLFields + _T(" FROM ") + sTableName + _T(" WHERE ") + sSQLWhere; if (!strSQLRule.empty())
strSQL = strSQL + _T(" ") + strSQLRule; //run sql
HRESULT hTRes = pRecordset.CreateInstance(__uuidof(Recordset));
if (!SUCCEEDED(hTRes))
throw -1; hTRes = pRecordset->Open(strSQL.c_str(), m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockPessimistic, adCmdText);
if (!SUCCEEDED(hTRes))
throw -1; if (pRecordset->ADOEOF)
throw -2; //save the data to entity list
pRecordset->MoveFirst();
while (!pRecordset->ADOEOF)
{
//create new pety from EntityFactory
//通过factory得到entity对应的entity class
PIEntity pety = m_pIEntityFactory->CreateEntity(list->GetEntityName()); _variant_t vIndex;
for (short i = 0; i < pRecordset->Fields->Count; ++i)
{
vIndex = i;
FieldPtr pFld = pRecordset->Fields->GetItem(&vIndex); _variant_t varFieldValue = pFld->GetValue();
if (VT_NULL == varFieldValue.vt)
continue; TSTRING strFieldName = pFld->GetName();
pety->SetAttributeValue(strFieldName, varFieldValue);
} //add entity to list
list->AddEntity(pety); //move to next record
pRecordset->MoveNext();
} pRecordset->Close();
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CANNOT_EXE_SQLSTMT;
} return nError;
}
文件:EntityListImpl.h
EntityList是使用vector实现的#pragma once#include "IEntityList.h"class CEntityListImpl :
public IEntityList
{
public:
CEntityListImpl(const TSTRING & sEntityName = _T(""));
~CEntityListImpl(void); void Release(); TSTRING GetEntityName();
void SetEntityName(const TSTRING & sEntityName); int GetEntityCount(); void AddEntity(PIEntity pety);
void RemoveEntity(int nIndex);
PIEntity GetEntity(int nIndex); void Clear();private:
BOOL __Validate(int nIndex);
};
#include ".\EntityListImpl.h"CEntityListImpl::CEntityListImpl(const TSTRING & sEntityName)
{
m_sEntityName = sEntityName;
}CEntityListImpl::~CEntityListImpl(void)
{
}void CEntityListImpl::Release()
{
Clear();
delete this;
}void CEntityListImpl::Clear()
{
//for (int i = 0; i < m_list.size() - 1; ++i)
// delete m_list[i]; m_list.clear();
}TSTRING CEntityListImpl::GetEntityName()
{
return m_sEntityName;
}void CEntityListImpl::SetEntityName(const TSTRING & sEntityName)
{
m_sEntityName = sEntityName;
}int CEntityListImpl::GetEntityCount()
{
return (int) m_list.size();
}void CEntityListImpl::AddEntity(PIEntity pety)
{
m_list.push_back(pety);
}void CEntityListImpl::RemoveEntity(int nIndex)
{
if (__Validate(nIndex))
{
//PIEntity pty = m_list[nIndex]; VECENTITY_IT it = find(m_list.begin(), m_list.end(), m_list[nIndex]);
m_list.erase(it); //delete pty;
}
}PIEntity CEntityListImpl::GetEntity(int nIndex)
{
if (__Validate(nIndex))
return m_list[nIndex];
else
return NULL;
}BOOL CEntityListImpl::__Validate(int nIndex)
{
return (0 <= nIndex && nIndex < (int) m_list.size());
}
粗略地看了一下,暴露给程序员的操作比较繁琐。
Delphi做主从表,没Java的ArrayList<>确实不太爽,不过可以用Collection来模拟
后来过了几年,hibernation就共享出来了,使用起来很方便
函数:InsertEntity(const PIEntity pety)
通过Entity生成一个Insert的SQL语句COMMON_ERR CDBGWImpl::InsertEntity(const PIEntity pety)
{
COMMON_ERR nError = COMMON_OK; try
{
//get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(pety->GetEntityName());
if (sTableName.empty())
throw -1; //get table field
//通过factory得到entity对应的table fields
VECFIELDS * pvecFields = m_pIEntityFactory->CreateEntityFields(pety->GetEntityName()); //set the insert sql
TSTRING strSQLFields, strSQLValues;
for (VECFIELDS_IT it = pvecFields->begin(); it != pvecFields->end(); ++it)
{
tagField & stuField = *it; //在Insert时候,有些字段的值有值,有些没有,以下的代码是把有值的字段的name
//写到SQL语句里,没有值的就不需要写. 但是PK必须要有值
if (pety->IsAttributeChanged(stuField.name))
{
_variant_t varFieldValue;
pety->GetAttributeValue(stuField.name, varFieldValue); TSTRING sFieldValue;
if (VT_NULL != varFieldValue.vt && VT_EMPTY != varFieldValue.vt)
{
strSQLFields = strSQLFields + _T("[") + sTableName + _T("].[") + stuField.name + _T("], ");
sFieldValue = Variant2String(varFieldValue); if (VT_BSTR == stuField.type || VT_DATE == stuField.type)
strSQLValues = strSQLValues + _T("'") + sFieldValue + _T("'") + _T(", ");
else
strSQLValues = strSQLValues + sFieldValue + _T(", ");
}
}
} if (strSQLValues.empty())
throw -1; //get rid of the last ',' in strSQLFields and strSQLValues
strSQLFields = strSQLFields.substr(0, strSQLFields.size() - 2);
strSQLValues = strSQLValues.substr(0, strSQLValues.size() - 2); //set SQL
TSTRING strSQL = _T("INSERT INTO ");
strSQL = strSQL + sTableName + _T(" (") + strSQLFields + _T(") VALUES(") + strSQLValues + _T(")"); //run sql
_variant_t RecordsAffected;
m_pConnection->Execute(strSQL.c_str(), &RecordsAffected, adCmdText);
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CANNOT_EXE_SQLSTMT;
} return nError;
}
函数:UpdateEntity(const PIEntity pety, const PIEntityList listCondition /* = NULL */)
通过Entity生成一个Update的SQL语句COMMON_ERR CDBGWImpl::UpdateEntity(const PIEntity pety, const PIEntityList listCondition /* = NULL */)
{
COMMON_ERR nError = COMMON_OK; try
{
//get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(pety->GetEntityName());
if (sTableName.empty())
throw -1; //get table field
//通过factory得到entity对应的table fields
VECFIELDS * pvecFields = m_pIEntityFactory->CreateEntityFields(pety->GetEntityName()); //set the insert sql
TSTRING strSQLSet;
for (VECFIELDS_IT it = pvecFields->begin(); it != pvecFields->end(); ++it)
{
tagField & stuField = *it; //在Update时候,有些字段的值改变了,有些没有,以下的代码是把改变的字段的name
//写到SQL语句里,没有改变的就不需要写, pk不能被修改
if (pety->IsAttributeChanged(stuField.name))
{
_variant_t varFieldValue;
pety->GetAttributeValue(stuField.name, varFieldValue); if (!stuField.is_pk)
{
TSTRING sFieldValue = Variant2String(varFieldValue); if (VT_BSTR == stuField.type || VT_DATE == stuField.type)
strSQLSet = strSQLSet + _T("[") + stuField.name + _T("] = '") + sFieldValue + _T("', ");
else
strSQLSet = strSQLSet + _T("[") + stuField.name + _T("] = ") + sFieldValue + _T(", ");
}
}
} if (strSQLSet.empty())
throw -1; //get rid of the last ',' in strSQLSet
strSQLSet = strSQLSet.substr(0, strSQLSet.size() - 2); //get where
//如果listCondition有值,则WHERE通过listCondition得到
//否则,就通过Entity的关键字段得到
TSTRING sSQLWhere;
if (listCondition && listCondition->GetEntityCount() > 0)
sSQLWhere = __GetCondition(pety->GetEntityName(), listCondition);
else
sSQLWhere = __GetPKCondition(pety); //set SQL
TSTRING strSQL = _T("UPDATE ");
if (sSQLWhere.empty())
strSQL = strSQL + sTableName + _T(" SET ") + strSQLSet;
else
strSQL = strSQL + sTableName + _T(" SET ") + strSQLSet + _T(" WHERE ") + sSQLWhere; //run sql
_variant_t RecordsAffected;
m_pConnection->Execute(strSQL.c_str(), &RecordsAffected, adCmdText);
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CANNOT_EXE_SQLSTMT;
} return nError;
}
C++的在哪下啊?
函数:DeleteEntity(const PIEntity pety, const PIEntityList listCondition /* = NULL */)通过Entity生成一个Delete的SQL语句COMMON_ERR CDBGWImpl::DeleteEntity(const PIEntity pety, const PIEntityList listCondition /* = NULL */)
{
COMMON_ERR nError = COMMON_OK; try
{
//get table name
//通过factory得到entity对应的table name
TSTRING sTableName = m_pIEntityFactory->GetTableName(pety->GetEntityName());
if (sTableName.empty())
throw -1; //get where
TSTRING sSQLWhere;
if (listCondition && listCondition->GetEntityCount() > 0)
sSQLWhere = __GetCondition(pety->GetEntityName(), listCondition);
else
sSQLWhere = __GetPKCondition(pety); //set SQL
TSTRING strSQL = _T("DELETE FROM ");
if (sSQLWhere.empty())
strSQL = strSQL + sTableName;
else
strSQL = strSQL + sTableName + _T(" WHERE ") + sSQLWhere; //run sql
_variant_t RecordsAffected;
m_pConnection->Execute(strSQL.c_str(), &RecordsAffected, adCmdText);
}
catch (COMMON_ERR & err)
{
nError = err;
}
catch(_com_error &e)
{
nError = ERROR_DBGW_CANNOT_EXE_SQLSTMT;
} return nError;
}