我在几年前曾经用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的代码没有实现)我会慢慢介绍源代码的原理

解决方案 »

  1.   

    基本原理
    数据库封装(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;
      

  2.   

    文件:IEntity.h
    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;
      

  3.   

    文件:IEntityList.h
    就是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;
      

  4.   

    文件:IEntityFactory
    主要是通过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;
      

  5.   

    文件:IDBGW.h
    这是数据库封装的接口代码,主要方法是
    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;
    };
      

  6.   

    文件:DBGWImpl.h
    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;};
      

  7.   

    文件:DBGWImpl.cpp
    这是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;
    }
      

  8.   

    文件:DBGWImpl.cpp
    函数: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;
    }
      

  9.   

    支持原创 就算在SQL 版 也盖章
      

  10.   

    LoadEntity主要是生成Select SQL语句
    通过Entity的表名,字段名和关键字段的值作为查询条件得到唯一一个记录
    DBGW其实就是通过一种映射把class程序映射成数据库操作,从而起到封装的作用
    对于外部应用程序是不需要了解数据库的具体操作,适合多人合作开发程序
    有人可以专门负责数据库,有人可以专门负责UI的设计,还有再做中间的商务逻辑
      

  11.   

    文件:DBGWImpl.cpp
    函数:____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;
    }
      

  12.   

    TSTRING 等等在SAMA.dll中有定义,在我的资源里有下载,都是一些常用代码
    GetStringFromVariant等有些函数还没有上传,在最新的SAMA代码里
      

  13.   

    文件:DBGWImpl.cpp
    函数:__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;
    }
      

  14.   

    文件:DBGWImpl.cpp
    函数: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;
    }
      

  15.   

    说到这,顺便看看EntityList的实现
    文件: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);
    };
      

  16.   

    文件:EntityList.cpp#include "StdAfx.h"
    #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());
    }
      

  17.   

    一个OR/Mapping?
    粗略地看了一下,暴露给程序员的操作比较繁琐。
    Delphi做主从表,没Java的ArrayList<>确实不太爽,不过可以用Collection来模拟
      

  18.   

    我很多年前也用Java写过一个类似的DBGW,不过,可惜,后来代码给丢了
    后来过了几年,hibernation就共享出来了,使用起来很方便
      

  19.   

    文件:DBGWImpl.cpp
    函数: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;
    }
      

  20.   

    文件:DBGWImpl.cpp
    函数: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;
    }
      

  21.   

    楼主。你给的下载是delphi的。
    C++的在哪下啊?
      

  22.   

    文件:DBGWImpl.cpp
    函数: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;
    }
      

  23.   

    楼主我在等你呢。你要是没事就发给我呗嘿嘿。 qq邮箱  [email protected]
      

  24.   

    你的这个是CB代码吗?VC能用吗?