/*基类:*/
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