C++实现的ORM映射工具主要类介绍(一)

 

/*基类:*/

template <typename T>
class OrmDBBase{
public:
 virtual int save(T t)=0;

 virtual int update(T t)=0;

 virtual int del(T t)=0;

 virtual list<T> selList(string selSql)=0;
   
};

 ===================================================================

/*对外接口*/

template <typename T>
class OrmDao{
private:
 Connection *pConnection;
public:
 OrmDao(Connection *pConnection)
 {
  this->pConnection=pConnection;
 }

 ~OrmDao()
 {
  OrmDBManager<T>::Destroy();
 }

 /*保存单个对象*/
 int save(T t)
 {
  try{
   return OrmDBManager<T>::getInstance(pConnection)->save(t);
  }catch(ORMException &e){
   throw;
  }
 }

 /*更新单个对象:主键作为条件*/
 int update(T t)
 {
  try{
   return OrmDBManager<T>::getInstance(pConnection)->update(t);
  }catch(ORMException &e){
   throw;
  }
 }

 /*删除单个对象*/
 int del(T t)
 {
  try{
   return OrmDBManager<T>::getInstance(pConnection)->del(t);
  }catch(ORMException &e){
   throw;
  }
 }

 /*查询语句*/
 list<T> selList(string selSql)
 {
  try{
   return OrmDBManager<T>::getInstance(pConnection)->selList(selSql);
  }catch(ORMException &e){
   throw;
  }
 }

};

==================================================================

/*管理类*/

template <typename T>
class OrmDBManager{
private:
 static OrmDBManager<T> *pOrmDBManager;
 static OrmDBBase<T> *pOrmDBBase;
 Connection *pConnection;
public:
 OrmDBManager(Connection *pConnection)
 {
  this->pConnection=pConnection;
  string driver=DBManager::getInstance()->getDBConfig()->getDataSouce()->getDriver();
  if (driver=="oracle"){
   pOrmDBBase=new OrmDBOracle<T>(pConnection);
  }
 }

 static void Destroy()
 {
  cout<<T::getTableName()<<"  OrmDBManager<T>::Destroy()"<<endl;
  if (pOrmDBManager!=NULL){
   delete pOrmDBManager;
   pOrmDBManager=NULL;
  }
  if (pOrmDBBase!=NULL){
   delete pOrmDBBase;
   pOrmDBBase=NULL;
  }
 }

 static OrmDBManager * getInstance(Connection *pConnection)
 {
  if (pOrmDBManager==NULL){
   pOrmDBManager=new OrmDBManager<T>(pConnection);
  }
  return pOrmDBManager;
 }

 int save(T t)
 {
  try{
   return pOrmDBBase->save(t);
  }catch(ORMException &e){
   throw;
  }
 }

 int update(T t)
 {
  try{
   return pOrmDBBase->update(t);
  }catch(ORMException &e){
   throw;
  }
 }

 int del(T t)
 {
  try{
   return pOrmDBBase->del(t);
  }catch(ORMException &e){
   throw;
  }
 }

 list<T> selList(string selSql)
 {
  try{
   return pOrmDBBase->selList(selSql);
  }catch(ORMException &e){
   throw;
  }
 }

};

template <typename T>
OrmDBManager<T> * OrmDBManager<T>::pOrmDBManager=NULL;

template <typename T>
OrmDBBase<T>* OrmDBManager<T>::pOrmDBBase=NULL;

=====================================================================

/*具体oracle实现类*/

#ifndef  _ORMDBORACLE_HPP_
#define  _ORMDBORACLE_HPP_

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include "ComFun.hpp"
#include "DBField.hpp"
#include "DBTable.hpp"
#include "DataSouce.hpp"
#include "DBMapping.hpp"
#include "DBConfig.hpp"
#include "DBManager.hpp"
#include "BeanProxy.hpp"
#include "LibraryMgr.hpp"
#include "OrmDBBase.hpp"
#include "Connection.hpp"
#include "DateTime.hpp"
#define  OTL_ORA9I
#include <otlv4.h>
#include "ORMException.hpp"

using namespace std;

template <typename T>
struct TypeTraits;

template<>
struct TypeTraits<int>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  int *pColContent=NULL;
  try{
   pColContent=new int();
   otlStream>>*pColContent;
   pBeanProxy->execVoidMethod(methodName,(void *)pColContent);
   delete pColContent;
   pColContent=NULL;
  }catch(otl_exception& p){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template<>
struct TypeTraits<long>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  long *pColContent=NULL;
  try{
   pColContent=new long();
   otlStream>>*pColContent;
   pBeanProxy->execVoidMethod(methodName,(void *)pColContent);
   delete pColContent;
   pColContent=NULL;
  }catch(otl_exception& p){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template<>
struct TypeTraits<float>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  float *pColContent=NULL;
  try{
   pColContent=new float();
   otlStream>>*pColContent;
   pBeanProxy->execVoidMethod(methodName,(void *)pColContent);
   delete pColContent;
   pColContent=NULL;
  }catch(otl_exception& p){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template<>
struct TypeTraits<double>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  double *pColContent=NULL;
  try{
   pColContent=new double();
   otlStream>>*pColContent;
   pBeanProxy->execVoidMethod(methodName,(void *)pColContent);
   delete pColContent;
   pColContent=NULL;
  }catch(otl_exception& p){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template<>
struct TypeTraits<char>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  char *pColContent=NULL;
  try{
   pColContent=new char[pDBField->getLength()+1];
   memset(pColContent,0,pDBField->getLength()+1);
   otlStream>>pColContent;
   string str=string(pColContent);
   pBeanProxy->execVoidMethod(methodName,(void *)&str);
   delete pColContent;
   pColContent=NULL;
  }catch(otl_exception& p){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pColContent!=NULL){
    delete pColContent;
    pColContent=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template<>
struct TypeTraits<CDateTime>{
 static void setAttriValue(otl_stream &otlStream,BeanProxy *pBeanProxy,string methodName,DBField * pDBField)
 {
  CDateTime *pCDateTime=NULL;
  try{
   otl_datetime oltDt;
   otlStream>>oltDt;
   pCDateTime=new CDateTime(oltDt.year,oltDt.month,oltDt.day,oltDt.hour,oltDt.minute,oltDt.second);
   pBeanProxy->execVoidMethod(methodName,(void *)pCDateTime);
   delete pCDateTime;
   pCDateTime=NULL;
  }catch(otl_exception& p){
   if (pCDateTime!=NULL){
    delete pCDateTime;
    pCDateTime=NULL;
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pCDateTime!=NULL){
    delete pCDateTime;
    pCDateTime=NULL;
   }
   throw ORMException(e.what());
  }
 }
};

template <typename T>
class OrmDBOracle : public OrmDBBase<T>{
private:
 Connection *pConnection;
 otl_connect *pOtlConn;
 bool showSql;
 string    tableName;
 DBTable   *pDBTable;
 BeanProxy *pBeanProxy;

 void printSql(string sql)
 {
  if (showSql==true){
   cout<<sql<<endl;
  }
 }

 /*获得列表*/
 void getColumnList(map<string,DBField *> fieldsMap,vector<string> &colVector,vector<string> &colVarVector,int seq)
 {
  colVector.clear();
  colVarVector.clear();
  map<string,DBField *>::iterator iterField=fieldsMap.begin();
  while(iterField!=fieldsMap.end()){
   string colName=iterField->first;
   DBField *pDBField=(DBField *)iterField->second;
   string sqlType=pDBField->getSqlType();
   colVector.push_back(colName);
   char tmpVal[10];
   memset(tmpVal,0,10);
   sprintf(tmpVal,"%d",seq);
   ComFun::trim(tmpVal);
   string paraSeq=":para"+string(tmpVal);
   if (sqlType=="int"||sqlType=="integer"){
    colVarVector.push_back(paraSeq+"<int>");
   }else if(sqlType=="date"){
    colVarVector.push_back(paraSeq+"<timestamp>");
   }else if (sqlType=="long"){
    colVarVector.push_back(paraSeq+"<long>");
   }else if (sqlType=="float"){
    colVarVector.push_back(paraSeq+"<float>");
   }else if (sqlType=="double"){
    colVarVector.push_back(paraSeq+"<double>");
   }else if (sqlType=="char"||sqlType=="varchar2"){
    memset(tmpVal,0,10);
    sprintf(tmpVal,"%d",pDBField->getLength()+1);
    ComFun::trim(tmpVal);
    string var="["+string(tmpVal)+"]";
    colVarVector.push_back(paraSeq+"<char"+var+">");
   }
   seq++;
   iterField++;
  }
 }

 /*给变量赋值*/
 void setVarValue(BeanProxy *pBeanProxy,otl_stream &otlStream,map<string,DBField *> fieldsMap)
 {
  try{
   map<string,DBField *>::iterator iterField=fieldsMap.begin();
   while(iterField!=fieldsMap.end()){
    string colName=ComFun::toLower(iterField->first);
    DBField *pDBField=(DBField *)iterField->second;
    string sqlType=pDBField->getSqlType();
    vector<string> subColVector;
    subColVector.clear();
    /*列名:拆分为*/
    subColVector=ComFun::split(colName,"_");
    string methodName="get";
    for(int i=0;i<subColVector.size();i++){
     string subCol=subColVector[i];
     methodName=methodName+ComFun::toUpper(subCol.substr(0,1))+subCol.substr(1,subCol.size()-1);;
    }
    /*获得属性值*/
    void *attrValue=pBeanProxy->execGetMethod(methodName);
    //cout<<"methodName:"<<methodName<<endl;
    if (sqlType=="int"||sqlType=="integer"){
     otlStream<<*(int *)attrValue;
    }else if (sqlType=="long"){
     otlStream<<*(long *)attrValue;
    }else if (sqlType=="float"){
     otlStream<<*(float *)attrValue;
    }else if (sqlType=="double"){
     otlStream<<*(double *)attrValue;
    }else if (sqlType=="char"||sqlType=="varchar2"){
     otlStream<<(*(string*)attrValue).c_str();
    }else if (sqlType=="date"){
     otl_datetime otlDt;
     CDateTime dt;
     string format=dt.getFormat();
     dt=*(CDateTime *)attrValue;
     otlDt.year=dt.getYear();
     otlDt.month=dt.getMonth();
     otlDt.day=dt.getDay();
     if (format.find("%H")!=-1&&format.find("%M")!=-1&&format.find("%S")!=-1){
      otlDt.hour=dt.getHour();
      otlDt.minute=dt.getMinute();
      otlDt.second=dt.getSecond();
     }
     if (dt.getTime()>0){
      otlStream<<otlDt;
     }else{
      otlStream<<otl_null();
     }
    }
    iterField++;
   }
  }catch(otl_exception& p){
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   throw ORMException(e.what());
  }
 }

public:
 OrmDBOracle(Connection *pConnection)
 {
  this->pConnection=pConnection;
  pOtlConn=(otl_connect *)pConnection->getConnection();
  showSql=DBManager::getInstance()->getDBConfig()->getDataSouce()->getShowSql();
  tableName=ComFun::toUpper(T::getTableName());
  pDBTable=DBManager::getInstance()->getDBConfig()->getDBMapping()->getTable(tableName);
  pBeanProxy=(BeanProxy *)LibraryMgr::getInstance()->getFunction(pDBTable->getClassName());
 }

 /*保存单个对象*/
 int save(T t)
 {
  try{
   string insertSql="insert into "+tableName+" ";
   map<string,DBField *> fieldsMap=pDBTable->getColumnsMap();
   if (fieldsMap.size()==0){
    return RET_FAIL;
   }
   insertSql=insertSql+"(";
   string valueSql=" values(";
   vector<string> colVector;
   vector<string> colVarVector;
   getColumnList(fieldsMap,colVector,colVarVector,1);
   for(int i=0;i<colVector.size();i++){
    if (i==colVector.size()-1){
     insertSql=insertSql+colVector[i];
     valueSql=valueSql+colVarVector[i];
    }else{
     insertSql=insertSql+colVector[i]+",";
     valueSql=valueSql+colVarVector[i]+",";
    }
   }
   insertSql=insertSql+") "+valueSql+")";
   printSql(insertSql);
   otl_stream otlInsert(1,insertSql.c_str(),*pOtlConn);
   otlInsert.set_commit(0);
   pBeanProxy->setBean(&t);
   setVarValue(pBeanProxy,otlInsert,fieldsMap);
   pBeanProxy->delPtr();
   return RET_SUCESS;
  }catch(otl_exception& p){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException(e.what());
  }
 }

 /*更新单个对象:主键作为条件*/
 int update(T t)
 {
  try{
   string updateSql="update "+tableName+" set ";
   map<string,DBField *> fieldsMap=pDBTable->getColumnsMap();
   map<string,DBField *> pkFieldsMap=pDBTable->getPKColumnsMap();
   map<string,DBField *> otherFieldsMap;
   otherFieldsMap.clear();
   if (fieldsMap.size()==0){
    return RET_FAIL;
   }

   if (pkFieldsMap.size()==0){
    return RET_FAIL;
   }
   map<string,DBField *>::iterator iterField=fieldsMap.begin();
   while(iterField!=fieldsMap.end()){
    string colName=iterField->first;
    DBField *pDBField=(DBField *)iterField->second;
    if (pkFieldsMap.count(colName)==0){
     otherFieldsMap[colName]=pDBField;
    }
    iterField++;
   }
   if (otherFieldsMap.size()==0){
    return RET_FAIL;
   }
   vector<string> colOtherVector;
   vector<string> colOtherVarVector;
   getColumnList(otherFieldsMap,colOtherVector,colOtherVarVector,1);
   for(int i=0;i<colOtherVector.size();i++){
    if (i==colOtherVector.size()-1){
     updateSql=updateSql+colOtherVector[i]+"="+colOtherVarVector[i];
    }else{
     updateSql=updateSql+colOtherVector[i]+"="+colOtherVarVector[i]+",";
    }
   }
   string whereSql="";
   vector<string> colPKVector;
   vector<string> colPKVarVector;
   getColumnList(pkFieldsMap,colPKVector,colPKVarVector,otherFieldsMap.size()+1);
   for(int i=0;i<colPKVector.size();i++){
    if (i==colPKVector.size()-1){
     whereSql=whereSql+colPKVector[i]+"="+colPKVarVector[i];
    }else{
     whereSql=whereSql+colPKVector[i]+"="+colPKVarVector[i]+" and ";
    }
   }
   updateSql=updateSql+" where "+whereSql;
   printSql(updateSql);
   otl_stream otlUpdate(1,updateSql.c_str(),*pOtlConn);
   otlUpdate.set_commit(0);
   pBeanProxy->setBean(&t);
   setVarValue(pBeanProxy,otlUpdate,otherFieldsMap);
   setVarValue(pBeanProxy,otlUpdate,pkFieldsMap);
   pBeanProxy->delPtr();
   return RET_SUCESS;
  }catch(otl_exception& p){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException(e.what());
  }

 }

 /*删除单个对象*/
 int del(T t)
 {
  try{
   string delSql="delete from "+tableName+" where ";
   map<string,DBField *> pkFieldsMap=pDBTable->getPKColumnsMap();
   if (pkFieldsMap.size()==0){
    return RET_FAIL;
   }
   string whereSql="";
   vector<string> colVector;
   vector<string> colVarVector;
   getColumnList(pkFieldsMap,colVector,colVarVector,1);
   for(int i=0;i<colVector.size();i++){
    if (i==colVector.size()-1){
     whereSql=whereSql+colVector[i]+"="+colVarVector[i];
    }else{
     whereSql=whereSql+colVector[i]+"="+colVarVector[i]+" and ";
    }
   }
   delSql=delSql+whereSql;
   printSql(delSql);
   otl_stream otlDel(1,delSql.c_str(),*pOtlConn);
   otlDel.set_commit(0);
   pBeanProxy->setBean(&t);
   setVarValue(pBeanProxy,otlDel,pkFieldsMap);
   pBeanProxy->delPtr();
   return RET_SUCESS;
  }catch(otl_exception& p){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   if (pBeanProxy!=NULL){
    pBeanProxy->delPtr();
   }
   throw ORMException(e.what());
  }
 }

 /*查询语句*/
 list<T> selList(string selSql)
 {
  otl_stream otlSelect;
  try{
   list<T> tmpList;
   tmpList.clear();
   int descLen = 0;
   otlSelect.set_commit(0);
   map<string,DBField *> fieldsMap=pDBTable->getColumnsMap();
   otlSelect.open(50,selSql.c_str(),*pOtlConn);
   otl_column_desc *desc=otlSelect.describe_select(descLen);
   while(!otlSelect.eof()){
    T t;
    //memset(&t,0,sizeof(T));
    pBeanProxy->setBean((void *)&t);
    for(int i=0;i<descLen;i++){
     string colName=string(ComFun::trim(desc[i].name));
     map<string,DBField *>::iterator iter = fieldsMap.find(colName);
     if (iter!=fieldsMap.end()){
      DBField * pDBField=(DBField *)iter->second;
      string sqlType=pDBField->getSqlType();
      colName=ComFun::toLower(colName);
      vector<string> subColVector;
      subColVector.clear();
      subColVector=ComFun::split(colName,"_");
      string methodName="set";
      for(int i=0;i<subColVector.size();i++){
       string subCol=subColVector[i];
       methodName=methodName+ComFun::toUpper(subCol.substr(0,1))+subCol.substr(1,subCol.size()-1);;
      }
      if (sqlType=="int"||sqlType=="integer"){
       TypeTraits<int>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }else if (sqlType=="long"){
       TypeTraits<long>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }else if (sqlType=="float"){
       TypeTraits<float>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }else if (sqlType=="double"){
       TypeTraits<double>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }else if (sqlType=="char"||sqlType=="varchar2"){
       TypeTraits<char>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }else if (sqlType=="date"){
       TypeTraits<CDateTime>::setAttriValue(otlSelect,pBeanProxy,methodName,pDBField);
      }
     }
    }
    tmpList.push_back(t);
   }
   otlSelect.close();
   return tmpList;
  }catch(otl_exception& p){
   otlSelect.close();
   throw ORMException((const char *)p.msg);
  }catch(exception &e){
   otlSelect.close();
   throw ORMException(e.what());
  }
 }

};

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值