C++ ADO的数据库连接池

此连接池用于管理数据库的多个连接,主要思想如下:

1)按照传入的参数起N个连接来连接数据库(参数中有最小连接数N,最大连接数M)。

2)建立一个空闲队列(初始化的N个连接放到空闲队列),一个使用队列来管理,使用的时候重空闲队列抓取一个连接,丢到使用队列,

如果空闲队列没有可用连接,并且连接数小于允许的最大连接数(<M)则创建一个新的连接,否则等待。

3)起一个守护线程,发现用过的连接,则使用队列中移除,添加到空闲队列,无效的链接则删除。

代码如下,

首先是头文件,因为导出的是DLL,文件中的RFIDAPI定义如下

#ifdef _USRDLL
#define RFIDAPI _declspec(dllexport)
#else 
#define RFIDAPI _declspec(dllimport)

view plaincopy to clipboardprint?
01.// DBConnPool.h: interface for the DBConnPool class.   
02.//   
03.//   
04.#if !defined(AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_)   
05.#define AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_   
06.#define  SQL_BUFFER_LEN 1024   
07.#import "C:/Program Files/Common Files/System/ado/msado15.dll" rename("EOF","ADOEOF")   
08.#include <list>   
09.#include <windows.h>   
10.#include <string>   
11.#include <vector>   
12.#include  "DBDefine.h"   
13.using namespace ADODB;   
14.using namespace std;   
15.class RFIDAPI DBConnect   
16.{   
17.public:   
18.    DBConnect(LPCSTR strDstAddress,    
19.              LPCSTR strUsername,    
20.              LPCSTR strPassword,      
21.              LPCSTR strDBName,   
22.              BOOL &state);   
23.    ~DBConnect();   
24.public:   
25.    // 连接到数据库   
26.       
27.    int Open(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName);   
28.    // 关闭数据库   
29.       
30.    int Close();   
31.    // 数据库是否已连接   
32.       
33.    BOOL IsOpen() const;   
34.public:   
35.private:   
36.    ADODB::_ConnectionPtr           _connection_ptr;   //ADO的数据库连接智能指针   
37.    bool                            _isAdoValid;       //ADO环境是否已经初化成功标志量   
38.    bool                            m_bDBOpen;   
39.       
40.    LPCSTR                          _strDstAddress;    //数据源地址或服务名   
41.    LPCSTR                          _strUsername;      //数据库用户名   
42.    LPCSTR                          _strPassword;      //数据库密码   
43.    LPCSTR                          _strDBName;        //数据库名称   
44.    void         VarientToString(_variant_t var, string& str);   
45.    //对外公共接口   
46.public:   
47.    int          GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms);       
48.       
49.    int          InsertHistory(int id);   
50.    int          UserLogin(LPCSTR name,LPCSTR password);   
51.};     
52.typedef std::list<DBConnect*> DBConnectList;   
53.class  DBConnPool     
54.{   
55.public:   
56.    DBConnPool();   
57.    virtual ~DBConnPool();   
58.    // 获取实例指针   
59.    static DBConnPool * Instanse();   
60.    // 初始化所有连接   
61.    int InitializeAllDBConnections();   
62.       
63.    // 关闭所有连接   
64.    void DestroyAllDBConnections();   
65.    // 获取一个空闲连接   
66.    DBConnect* GetAConnection();   
67.    // 交还连接给空闲队列   
68.    int RestoreAConnection(DBConnect* pDBEngine);   
69.    void SetDBInfo(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);   
70.private:   
71.       
72.    // 创建一个连接   
73.    int InitializeAConnection();   
74.    // 关闭一个连接   
75.    void CloseAConnection(DBConnect* pDBEngine);   
76.    // 停止工作线程   
77.    void StopThread();   
78.       
79.    // 判断是否需要停止   
80.    BOOL IsNeedStop();   
81.    BOOL IsNeedConnection();   
82.    // 将守卫类作为连接池类的友元类   
83.    friend class ConnGuard;   
84.    // 唯一实例   
85.    static DBConnPool *m_pInstanse;   
86.       
87.    // 空闲数据库连接队列   
88.    DBConnectList m_listIdleConnection;   
89.    // 在使用的数据库连接   
90.    DBConnectList m_listBusyConnection;   
91.       
92.    // 队列保护的临界区   
93.    CRITICAL_SECTION m_csIdleConnList;   
94.    CRITICAL_SECTION m_csBusyConnList;   
95.       
96.    // 可用连接总数的三个指标:最大、最小   
97.    int m_nMaxCount;   
98.    int m_nMinCount;   
99.       
100.//  // 数据库信息   
101.    LPCSTR                          _strDstAddress;    //数据源地址或服务名   
102.    LPCSTR                          _strUsername;      //数据库用户名   
103.    LPCSTR                          _strPassword;      //数据库密码   
104.    LPCSTR                          _strDBName;        //数据库名称   
105.       
106.    // 维护线程   
107.    HANDLE m_hMaintanceThread; // 线程句柄   
108.    HANDLE m_hHaveData; // 信号   
109.       
110.    BOOL m_bNeedStop; // 管理线程起停的标志位   
111.    BOOL m_bNeedConnection; // 需要创建连接的标志   
112.    static  DWORD   WINAPI  thread_run( LPVOID pdata);   
113.};   
114.// 守卫类,利用构造和析构函数保证连接取出和归还必须成对,防止资源泄露   
115.class  DBConnGuard   
116.{   
117.public:   
118.    DBConnGuard(DBConnect*& DBConn)   
119.    {   
120.        DBConn = DBConnPool::Instanse()->GetAConnection();   
121.        m_pDBConn = DBConn;   
122.    }   
123.    virtual ~DBConnGuard()   
124.    {   
125.        DBConnPool::Instanse()->RestoreAConnection(m_pDBConn);   
126.    }   
127.private:   
128.    DBConnect *m_pDBConn;   
129.};   
130.RFIDAPI void  InitDBIterface(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);   
131.RFIDAPI DBConnect * GetAConnect();   
132.#endif // !defined(AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_)  
// DBConnPool.h: interface for the DBConnPool class.
//
//
#if !defined(AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_)
#define AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_
#define  SQL_BUFFER_LEN 1024
#import "C:/Program Files/Common Files/System/ado/msado15.dll" rename("EOF","ADOEOF")
#include <list>
#include <windows.h>
#include <string>
#include <vector>
#include  "DBDefine.h"
using namespace ADODB;
using namespace std;
class RFIDAPI DBConnect
{
public:
 DBConnect(LPCSTR strDstAddress, 
     LPCSTR strUsername, 
        LPCSTR strPassword, 
        LPCSTR strDBName,
     BOOL &state);
 ~DBConnect();
public:
 // 连接到数据库
 
 int Open(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName);
 // 关闭数据库
 
 int Close();
 // 数据库是否已连接
 
 BOOL IsOpen() const;
public:
private:
 ADODB::_ConnectionPtr           _connection_ptr;   //ADO的数据库连接智能指针
 bool                            _isAdoValid;       //ADO环境是否已经初化成功标志量
 bool       m_bDBOpen;
 
 LPCSTR       _strDstAddress;    //数据源地址或服务名
 LPCSTR       _strUsername;      //数据库用户名
 LPCSTR       _strPassword;      //数据库密码
 LPCSTR       _strDBName;        //数据库名称
 void         VarientToString(_variant_t var, string& str);
 //对外公共接口
public:
 int          GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms);    
 
 int          InsertHistory(int id);
 int          UserLogin(LPCSTR name,LPCSTR password);
}; 
typedef std::list<DBConnect*> DBConnectList;
class  DBConnPool  
{
public:
 DBConnPool();
 virtual ~DBConnPool();
 // 获取实例指针
 static DBConnPool * Instanse();
 // 初始化所有连接
 int InitializeAllDBConnections();
 
 // 关闭所有连接
 void DestroyAllDBConnections();
 // 获取一个空闲连接
 DBConnect* GetAConnection();
 // 交还连接给空闲队列
 int RestoreAConnection(DBConnect* pDBEngine);
 void SetDBInfo(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);
private:
 
 // 创建一个连接
 int InitializeAConnection();
 // 关闭一个连接
 void CloseAConnection(DBConnect* pDBEngine);
 // 停止工作线程
 void StopThread();
 
 // 判断是否需要停止
 BOOL IsNeedStop();
 BOOL IsNeedConnection();
 // 将守卫类作为连接池类的友元类
 friend class ConnGuard;
 // 唯一实例
 static DBConnPool *m_pInstanse;
 
 // 空闲数据库连接队列
 DBConnectList m_listIdleConnection;
 // 在使用的数据库连接
 DBConnectList m_listBusyConnection;
 
 // 队列保护的临界区
 CRITICAL_SECTION m_csIdleConnList;
 CRITICAL_SECTION m_csBusyConnList;
 
 // 可用连接总数的三个指标:最大、最小
 int m_nMaxCount;
 int m_nMinCount;
 
//  // 数据库信息
 LPCSTR       _strDstAddress;    //数据源地址或服务名
 LPCSTR       _strUsername;      //数据库用户名
 LPCSTR       _strPassword;      //数据库密码
 LPCSTR       _strDBName;        //数据库名称
 
 // 维护线程
 HANDLE m_hMaintanceThread; // 线程句柄
 HANDLE m_hHaveData; // 信号
 
 BOOL m_bNeedStop; // 管理线程起停的标志位
 BOOL m_bNeedConnection; // 需要创建连接的标志
 static DWORD WINAPI thread_run( LPVOID pdata);
};
// 守卫类,利用构造和析构函数保证连接取出和归还必须成对,防止资源泄露
class  DBConnGuard
{
public:
 DBConnGuard(DBConnect*& DBConn)
 {
        DBConn = DBConnPool::Instanse()->GetAConnection();
  m_pDBConn = DBConn;
 }
 virtual ~DBConnGuard()
 {
  DBConnPool::Instanse()->RestoreAConnection(m_pDBConn);
 }
private:
 DBConnect *m_pDBConn;
};
RFIDAPI void  InitDBIterface(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);
RFIDAPI DBConnect * GetAConnect();
#endif // !defined(AFX_DBCONNPOOL_H__42089E9A_FD85_4DD4_A973_64A4980332A5__INCLUDED_)
 

下面是实现文件,

view plaincopy to clipboardprint?
01.// DBConnPool.cpp: implementation of the DBConnPool class.   
02.//   
03.//   
04.#include "stdafx.h"   
05.#include "DBConnPool.h"   
06.DBConnect * pDBConn = NULL;   
07.void InitDBIterface(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)   
08.{   
09.    DBConnPool::Instanse()->SetDBInfo(strDstAddress,strUsername,strPassword,strDBName,minConn,maxConn);   
10.    int cout = DBConnPool::Instanse()->InitializeAllDBConnections();   
11.}   
12.DBConnect * GetAConnect()   
13.{   
14.    DBConnGuard oConnGuard(pDBConn);   
15.    return pDBConn;   
16.}   
17.//DBConnect/   
18.DBConnect::DBConnect(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName,BOOL &state)   
19.{   
20.   m_bDBOpen = false;   
21.   if (0 == Open(strDstAddress,strUsername,strPassword,strDBName))   
22.   {   
23.        state =true;   
24.   }   
25.   else  
26.   {   
27.       state = false;   
28.   }   
29.}   
30.DBConnect::~DBConnect()   
31.{   
32.   Close();   
33.}   
34.int DBConnect::Open(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName)   
35.{   
36.    _strDstAddress = strDstAddress;   
37.    _strDBName       = strDBName;   
38.    _strUsername     = strUsername;   
39.    _strPassword     = strPassword;   
40.       
41.    HRESULT comhr = ::CoInitialize(NULL);   
42.    if (FAILED(comhr))   
43.           
44.    {   
45.        return -1;   
46.    }   
47.    HRESULT hr = _connection_ptr.CreateInstance(__uuidof(Connection));   
48.       
49.    if (FAILED(hr))   
50.    {   
51.        return -1;   
52.    }   
53.       
54.    char szSQL[SQL_BUFFER_LEN] = {0};   
55.    memset(szSQL, 0, SQL_BUFFER_LEN);   
56.    sprintf(szSQL, "Driver=SQL Server;Server=%s;DATABASE=%s", strDstAddress, strDBName);   
57.       
58.    try  
59.    {   
60.        // 连接到服务器上数据库   
61.        _connection_ptr->Open(szSQL, strUsername, strPassword,adModeUnknown) ;   
62.        if (FAILED(hr))   
63.            return -1;   
64.    }   
65.    catch (_com_error &err)   
66.    {   
67.        TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);  
68.           
69.        return -1;   
70.    }   
71.       
72.    m_bDBOpen = TRUE;   
73.       
74.    return 0;   
75.}   
76.int DBConnect::Close()   
77.{   
78.    if (m_bDBOpen)   
79.    {   
80.        HRESULT hr =_connection_ptr->Close();   
81.           
82.        if (FAILED(hr))   
83.        {   
84.            return -1;   
85.        }   
86.        ::CoUninitialize();   
87.        m_bDBOpen = FALSE;   
88.    }   
89.       
90.    return 0;   
91.}   
92.int DBConnect::UserLogin(LPCSTR name,LPCSTR password)   
93.{   
94.    if (!m_bDBOpen)   
95.    {   
96.        return -1;   
97.    }   
98.    // 创建Command对象   
99.    _CommandPtr cmd;   
100.    HRESULT hr = cmd.CreateInstance(__uuidof(Command));   
101.    if (FAILED(hr))   
102.    {   
103.        return -1;   
104.    }   
105.       
106.    char szSQL[SQL_BUFFER_LEN] = {0};   
107.    sprintf(szSQL, "select count(*) as count from t_user where name =/'%s/' and password =/'%s/'",   
108.        name,password);   
109.    cmd->ActiveConnection = _connection_ptr;   
110.    cmd->CommandText = _bstr_t(szSQL);   
111.    cmd->CommandType = adCmdText;   
112.    try    
113.    {   
114.        _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);   
115.           
116.        if (FAILED(hr))    
117.        {   
118.            return -1;   
119.        }   
120.        _variant_t count;   
121.        while (!rs->ADOEOF)   
122.        {        
123.            count = rs->GetCollect("count");   
124.            rs->MoveNext() ;   
125.        }   
126.        if(count.intVal == 0)   
127.            return -1;   
128.    }   
129.    catch (_com_error &err)   
130.    {   
131.        TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);   
132.           
133.        return -1;   
134.    }   
135.    return 0;   
136.}   
137.int DBConnect::GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms)   
138.{   
139.    if (!m_bDBOpen)   
140.    {   
141.        return -1;   
142.    }   
143.    // 创建Command对象   
144.    _CommandPtr cmd;   
145.    HRESULT hr = cmd.CreateInstance(__uuidof(Command));   
146.    if (FAILED(hr))   
147.    {   
148.        return -1;   
149.    }   
150.    string strSql = "exec SP_SMS_GETSUBMIT";   
151.    cmd->ActiveConnection = _connection_ptr;   
152.    cmd->CommandText = _bstr_t(strSql.c_str());   
153.    cmd->CommandType = adCmdText;   
154.    try    
155.    {   
156.        _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);   
157.           
158.        if (FAILED(hr))    
159.        {   
160.            return -1;   
161.        }   
162.        while (!rs->ADOEOF)   
163.        {        
164.            _variant_t      id;   
165.            _variant_t      recverid;   
166.            _variant_t      recvertel;   
167.            _variant_t      messagecontent;   
168.            _variant_t      recverphonetype;   
169.            _variant_t      inout;   
170.            _variant_t      sendtime;   
171.            _variant_t      cardtime;   
172.            _variant_t      schoolid;   
173.            _variant_t      classid;   
174.            _variant_t      rfidno;   
175.               
176.            id = rs->GetCollect("id");   
177.            recverid = rs->GetCollect("recverid");   
178.            recvertel = rs->GetCollect("recvertel");   
179.            messagecontent = rs->GetCollect("messagecontent");   
180.            recverphonetype = rs->GetCollect("recverphonetype");   
181.            inout = rs->GetCollect("inout");   
182.            sendtime = rs->GetCollect("sendtime");   
183.            cardtime = rs->GetCollect("cardtime");   
184.            schoolid = rs->GetCollect("schoolid");   
185.            classid = rs->GetCollect("classid");   
186.            rfidno = rs->GetCollect("rfidno");   
187.            SOAP_SUBMIT_SMS submitsms;   
188.            submitsms.id = (int)(long)id;   
189.            VarientToString(recverid, submitsms.recverid);   
190.            VarientToString(recvertel, submitsms.recvertel);   
191.            VarientToString(messagecontent, submitsms.messagecontent);   
192.            VarientToString(recverphonetype, submitsms.recverphonetype);   
193.            submitsms.inout = (int)(long)inout;   
194.            VarientToString(sendtime, submitsms.sendtime);   
195.            VarientToString(cardtime, submitsms.cardtime);   
196.            VarientToString(rfidno, submitsms.rfidno);   
197.            submitsms.schoolid = (int)(long)schoolid;   
198.            submitsms.classid = (int)(long)classid;   
199.            vecsoapSms.push_back(submitsms);   
200.            rs->MoveNext() ;   
201.        }   
202.    }   
203.    catch (_com_error &err)   
204.    {   
205.        TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);   
206.           
207.        return -1;   
208.    }   
209.    return 0;   
210.}   
211.int DBConnect::InsertHistory(int id)   
212.{   
213.    if (!m_bDBOpen)   
214.    {   
215.        return -1;   
216.    }   
217.    // 创建Command对象   
218.    _CommandPtr cmd;   
219.    HRESULT hr = cmd.CreateInstance(__uuidof(Command));   
220.    if (FAILED(hr))   
221.    {   
222.        return -1;   
223.    }   
224.    char szSQL[SQL_BUFFER_LEN] = {0};   
225.    sprintf(szSQL, "exec SP_SMS_SUBMITRESULT %d", id);   
226.    try  
227.    {   
228.        cmd->ActiveConnection = _connection_ptr;   
229.        cmd->CommandText = _bstr_t(szSQL);   
230.        cmd->CommandType = adCmdText;   
231.        cmd->Execute(NULL, NULL, adCmdUnknown);   
232.    }   
233.    catch (_com_error &err)   
234.    {   
235.        TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);   
236.           
237.        return -1;   
238.    }   
239.    return 0;   
240.}   
241.void DBConnect::VarientToString(_variant_t var, string& str)   
242.{   
243.    if (VT_NULL == var.vt)   
244.    {   
245.        str = "";   
246.    }   
247.    else  
248.    {   
249.        str = (char*)_bstr_t(var);   
250.    }   
251.}   
252.//End//   
253.//   
254.// Construction/Destruction   
255.//   
256.DBConnPool* DBConnPool::m_pInstanse = NULL;   
257.DBConnPool::DBConnPool()   
258.{   
259.    m_bNeedStop = FALSE;   
260.    m_bNeedConnection = FALSE;   
261.    m_hMaintanceThread = INVALID_HANDLE_VALUE;   
262.       
263.    // 线程控制   
264.    m_hHaveData = CreateEvent (NULL, TRUE, FALSE, _T("DataConnPool"));   
265.       
266.       
267.    InitializeCriticalSection(&m_csIdleConnList);   
268.    InitializeCriticalSection(&m_csBusyConnList);   
269.}   
270.void DBConnPool::SetDBInfo(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)   
271.{   
272.    _strDBName = strDBName;   
273.    _strDstAddress = strDstAddress;   
274.    _strPassword = strPassword;   
275.    _strUsername = strUsername;   
276.     m_nMaxCount = maxConn;   
277.     m_nMinCount = minConn;   
278.}   
279.DBConnPool::~DBConnPool()   
280.{   
281.    m_hMaintanceThread = INVALID_HANDLE_VALUE;   
282.    m_bNeedStop = TRUE;   
283.    CloseHandle(m_hHaveData);   
284.    CloseHandle(m_hMaintanceThread);   
285.       
286.    DeleteCriticalSection(&m_csIdleConnList);   
287.    DeleteCriticalSection(&m_csBusyConnList);   
288.}   
289.DBConnPool *DBConnPool::Instanse()   
290.{   
291.    if (NULL == m_pInstanse)   
292.    {   
293.        m_pInstanse = new DBConnPool();   
294.    }   
295.    return m_pInstanse;   
296.}   
297.int DBConnPool::InitializeAllDBConnections()   
298.{   
299.    // 先七公里现有的数据   
300.    DestroyAllDBConnections();   
301.    // 开始按照最小数量开始创建   
302.    DBConnect * pDBConnect = NULL;   
303.    int nCount = 0;   
304.    for (int i = 0; i < m_nMinCount; i++)   
305.    {   
306.        nCount = InitializeAConnection();   
307.    }   
308.    // 创建一个工作线程,用来进行一些后台维护工作   
309.    if (INVALID_HANDLE_VALUE == m_hMaintanceThread)   
310.    {   
311.        m_hMaintanceThread = CreateThread(NULL, NULL, thread_run, (LPVOID)this, 0, NULL);   
312.    }   
313.    return nCount;   
314.}   
315.void DBConnPool::DestroyAllDBConnections()   
316.{   
317.    // 销毁数据库连接可以使用大锁   
318.    EnterCriticalSection(&m_csIdleConnList);   
319.    DBConnectList::iterator itIdle = m_listIdleConnection.begin();   
320.    DBConnectList::iterator itIdleEnd = m_listIdleConnection.end();   
321.    while (itIdle != itIdleEnd)   
322.    {   
323.        if (NULL != (*itIdle))   
324.        {   
325.            (*itIdle)->Close();   
326.            delete (*itIdle);   
327.        }   
328.        // erase本身就会把跌代器指向下一个   
329.        itIdle = m_listIdleConnection.erase(itIdle);   
330.    }   
331.    LeaveCriticalSection(&m_csIdleConnList);   
332.    // 还有使用中的连接   
333.    EnterCriticalSection(&m_csBusyConnList);   
334.    DBConnectList::iterator itBusy = m_listBusyConnection.begin();   
335.    DBConnectList::iterator itBusyEnd = m_listBusyConnection.end();   
336.    while (itBusy != itBusyEnd)   
337.    {   
338.        if (NULL != (*itBusy))   
339.        {   
340.            (*itBusy)->Close();   
341.            delete (*itBusy);   
342.        }   
343.        // erase本身就会把跌代器指向下一个   
344.        itBusy = m_listBusyConnection.erase(itBusy);   
345.    }   
346.    LeaveCriticalSection(&m_csBusyConnList);   
347.}   
348.int DBConnPool::InitializeAConnection()   
349.{   
350.    BOOL bSuccess = FALSE;   
351.    DBConnect * pDBEngine = new DBConnect(_strDstAddress, _strUsername, _strPassword, _strDBName, bSuccess);   
352.    if (bSuccess)   
353.    {   
354.        m_bNeedConnection = FALSE;   
355.        return RestoreAConnection(pDBEngine);   
356.    }   
357.    else  
358.    {   
359.        delete pDBEngine;   
360.        return m_listIdleConnection.size();   
361.    }   
362.}   
363.void DBConnPool::CloseAConnection(DBConnect* pDBEngine)   
364.{   
365.    pDBEngine->Close();   
366.    // 从空闲队列将其删除   
367.    EnterCriticalSection(&m_csIdleConnList);   
368.    m_listIdleConnection.remove(pDBEngine);   
369.    LeaveCriticalSection(&m_csIdleConnList);   
370.}   
371.DBConnect * DBConnPool::GetAConnection()   
372.{   
373.    DBConnect * pDBEngine = NULL;   
374.    // 做一个循环,反复尝试五次取连接,每次间隔1秒钟   
375.    int nTimes = 0;   
376.    while ((m_listIdleConnection.size() <= 0) && (nTimes < 5))   
377.    {   
378.        Sleep(1000);   
379.        nTimes++;   
380.    }   
381.    if (5 == nTimes)   
382.    {   
383.        // 这样狼狈的进来肯定是没有可用连接了,记录日志退出   
384.    //  g_pSvrLog->AddRunLog(LL_ERROR, _T("Waiting for a connection for a long time, but failed."));   
385.        return pDBEngine;   
386.    }   
387.    // 从空闲队列中取出,并且加入到使用队列中   
388.    EnterCriticalSection(&m_csIdleConnList);   
389.    if (m_listIdleConnection.size() > 0)   
390.    {   
391.        pDBEngine = m_listIdleConnection.front();   
392.        m_listIdleConnection.pop_front();   
393.        // 加入使用的连接队列   
394.        EnterCriticalSection(&m_csBusyConnList);   
395.        m_listBusyConnection.push_back(pDBEngine);   
396.        LeaveCriticalSection(&m_csBusyConnList);   
397.    }   
398.    LeaveCriticalSection(&m_csIdleConnList);   
399.    if (m_listIdleConnection.size() <= 1)   
400.    {   
401.        // 剩余空闲连接的数目小于等于1个时候需要检查开始创建   
402.        if ((m_listIdleConnection.size() + m_listBusyConnection.size()) < m_nMaxCount)   
403.        {   
404.            // 还小于最大限制,可以创建   
405.            SetEvent(m_hHaveData);   
406.            m_bNeedConnection = TRUE;   
407.        }   
408.        else  
409.        {   
410.            // 超出限制了,做个记录吧   
411.            //g_pSvrLog->AddRunLog(LL_ERROR, _T("Database connection reached max count."));   
412.        }   
413.    }   
414.    return pDBEngine;   
415.}   
416.int DBConnPool::RestoreAConnection(DBConnect* pDBEngine)   
417.{   
418.    if (NULL != pDBEngine)   
419.    {   
420.        // 从使用中的队列取出   
421.        EnterCriticalSection(&m_csBusyConnList);   
422.        m_listBusyConnection.remove(pDBEngine);   
423.        LeaveCriticalSection(&m_csBusyConnList);   
424.        // 加入到空闲队列中   
425.        EnterCriticalSection(&m_csIdleConnList);   
426.        m_listIdleConnection.push_back(pDBEngine);   
427.        LeaveCriticalSection(&m_csIdleConnList);   
428.    }   
429.    EnterCriticalSection(&m_csIdleConnList);   
430.    int nCount = m_listIdleConnection.size();   
431.    LeaveCriticalSection(&m_csIdleConnList);   
432.    return nCount;   
433.}   
434.void DBConnPool::StopThread()   
435.{   
436.    m_bNeedStop = TRUE;   
437.    // 因为线程是无限制等待信号的,所以这里先把标志位置为停止,然后发信号让线程检测   
438.    SetEvent(m_hHaveData);   
439.    // 等待退出   
440.    WaitForSingleObject(m_hMaintanceThread, INFINITE);   
441.    CloseHandle(m_hMaintanceThread);   
442.}   
443.BOOL DBConnPool::IsNeedStop()   
444.{   
445.    return m_bNeedStop;   
446.}   
447.BOOL DBConnPool::IsNeedConnection()   
448.{   
449.    return m_bNeedConnection;   
450.}   
451./************************************************************************/  
452./* 维护线程                                                             */  
453./************************************************************************/  
454.DWORD WINAPI DBConnPool::thread_run( LPVOID pdata)   
455.{   
456.    DBConnPool * pConPool = (DBConnPool *) pdata;   
457.    while (!pConPool->IsNeedStop())   
458.    {   
459.        // 设置事件为无信号, 并且无限制等待   
460.        ResetEvent(pConPool->m_hHaveData);          
461.        WaitForSingleObject(pConPool->m_hHaveData, INFINITE);   
462.        if (pConPool->IsNeedConnection())   
463.        {   
464.        //  g_pSvrLog->AddRunLog(LL_DEBUG, _T("Create a new DB connection."));   
465.            pConPool->InitializeAConnection();   
466.        }   
467.    }   
468.    return 0;   
469.}  
// DBConnPool.cpp: implementation of the DBConnPool class.
//
//
#include "stdafx.h"
#include "DBConnPool.h"
DBConnect * pDBConn = NULL;
void InitDBIterface(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)
{
 DBConnPool::Instanse()->SetDBInfo(strDstAddress,strUsername,strPassword,strDBName,minConn,maxConn);
 int cout = DBConnPool::Instanse()->InitializeAllDBConnections();
}
DBConnect * GetAConnect()
{
 DBConnGuard oConnGuard(pDBConn);
 return pDBConn;
}
//DBConnect/
DBConnect::DBConnect(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName,BOOL &state)
{
   m_bDBOpen = false;
   if (0 == Open(strDstAddress,strUsername,strPassword,strDBName))
   {
        state =true;
   }
   else
   {
    state = false;
   }
}
DBConnect::~DBConnect()
{
   Close();
}
int DBConnect::Open(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName)
{
 _strDstAddress = strDstAddress;
 _strDBName       = strDBName;
 _strUsername     = strUsername;
 _strPassword     = strPassword;
 
 HRESULT comhr = ::CoInitialize(NULL);
 if (FAILED(comhr))
  
 {
  return -1;
 }
 HRESULT hr = _connection_ptr.CreateInstance(__uuidof(Connection));
 
 if (FAILED(hr))
 {
  return -1;
 }
 
 char szSQL[SQL_BUFFER_LEN] = {0};
 memset(szSQL, 0, SQL_BUFFER_LEN);
 sprintf(szSQL, "Driver=SQL Server;Server=%s;DATABASE=%s", strDstAddress, strDBName);
 
 try
 {
  // 连接到服务器上数据库
  _connection_ptr->Open(szSQL, strUsername, strPassword,adModeUnknown) ;
  if (FAILED(hr))
   return -1;
 }
 catch (_com_error &err)
 {
  TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
  
  return -1;
 }
 
 m_bDBOpen = TRUE;
 
 return 0;
}
int DBConnect::Close()
{
 if (m_bDBOpen)
 {
  HRESULT hr =_connection_ptr->Close();
  
  if (FAILED(hr))
  {
   return -1;
  }
  ::CoUninitialize();
  m_bDBOpen = FALSE;
 }
 
 return 0;
}
int DBConnect::UserLogin(LPCSTR name,LPCSTR password)
{
 if (!m_bDBOpen)
 {
  return -1;
 }
 // 创建Command对象
 _CommandPtr cmd;
 HRESULT hr = cmd.CreateInstance(__uuidof(Command));
 if (FAILED(hr))
 {
  return -1;
 }
 
 char szSQL[SQL_BUFFER_LEN] = {0};
 sprintf(szSQL, "select count(*) as count from t_user where name =/'%s/' and password =/'%s/'",
  name,password);
 cmd->ActiveConnection = _connection_ptr;
 cmd->CommandText = _bstr_t(szSQL);
 cmd->CommandType = adCmdText;
 try 
 {
  _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);
  
  if (FAILED(hr)) 
  {
   return -1;
  }
  _variant_t count;
  while (!rs->ADOEOF)
  {     
   count = rs->GetCollect("count");
   rs->MoveNext() ;
  }
  if(count.intVal == 0)
   return -1;
 }
 catch (_com_error &err)
 {
  TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
  
  return -1;
 }
 return 0;
}
int DBConnect::GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms)
{
 if (!m_bDBOpen)
 {
  return -1;
 }
 // 创建Command对象
 _CommandPtr cmd;
 HRESULT hr = cmd.CreateInstance(__uuidof(Command));
 if (FAILED(hr))
 {
  return -1;
 }
    string strSql = "exec SP_SMS_GETSUBMIT";
 cmd->ActiveConnection = _connection_ptr;
 cmd->CommandText = _bstr_t(strSql.c_str());
 cmd->CommandType = adCmdText;
 try 
 {
  _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);
  
  if (FAILED(hr)) 
  {
   return -1;
  }
  while (!rs->ADOEOF)
  {     
   _variant_t  id;
   _variant_t  recverid;
   _variant_t  recvertel;
   _variant_t  messagecontent;
   _variant_t  recverphonetype;
   _variant_t  inout;
   _variant_t  sendtime;
   _variant_t  cardtime;
   _variant_t  schoolid;
   _variant_t  classid;
      _variant_t  rfidno;
   
   id = rs->GetCollect("id");
   recverid = rs->GetCollect("recverid");
   recvertel = rs->GetCollect("recvertel");
   messagecontent = rs->GetCollect("messagecontent");
   recverphonetype = rs->GetCollect("recverphonetype");
   inout = rs->GetCollect("inout");
   sendtime = rs->GetCollect("sendtime");
   cardtime = rs->GetCollect("cardtime");
   schoolid = rs->GetCollect("schoolid");
   classid = rs->GetCollect("classid");
   rfidno = rs->GetCollect("rfidno");
   SOAP_SUBMIT_SMS submitsms;
   submitsms.id = (int)(long)id;
   VarientToString(recverid, submitsms.recverid);
         VarientToString(recvertel, submitsms.recvertel);
   VarientToString(messagecontent, submitsms.messagecontent);
            VarientToString(recverphonetype, submitsms.recverphonetype);
   submitsms.inout = (int)(long)inout;
   VarientToString(sendtime, submitsms.sendtime);
   VarientToString(cardtime, submitsms.cardtime);
   VarientToString(rfidno, submitsms.rfidno);
   submitsms.schoolid = (int)(long)schoolid;
   submitsms.classid = (int)(long)classid;
   vecsoapSms.push_back(submitsms);
   rs->MoveNext() ;
  }
 }
 catch (_com_error &err)
 {
  TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
  
  return -1;
 }
 return 0;
}
int DBConnect::InsertHistory(int id)
{
 if (!m_bDBOpen)
 {
  return -1;
 }
 // 创建Command对象
 _CommandPtr cmd;
 HRESULT hr = cmd.CreateInstance(__uuidof(Command));
 if (FAILED(hr))
 {
  return -1;
 }
 char szSQL[SQL_BUFFER_LEN] = {0};
 sprintf(szSQL, "exec SP_SMS_SUBMITRESULT %d", id);
 try
 {
  cmd->ActiveConnection = _connection_ptr;
  cmd->CommandText = _bstr_t(szSQL);
  cmd->CommandType = adCmdText;
  cmd->Execute(NULL, NULL, adCmdUnknown);
 }
 catch (_com_error &err)
 {
  TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
  
  return -1;
 }
 return 0;
}
void DBConnect::VarientToString(_variant_t var, string& str)
{
 if (VT_NULL == var.vt)
 {
  str = "";
 }
 else
 {
  str = (char*)_bstr_t(var);
 }
}
//End//
//
// Construction/Destruction
//
DBConnPool* DBConnPool::m_pInstanse = NULL;
DBConnPool::DBConnPool()
{
 m_bNeedStop = FALSE;
 m_bNeedConnection = FALSE;
 m_hMaintanceThread = INVALID_HANDLE_VALUE;
 
 // 线程控制
 m_hHaveData = CreateEvent (NULL, TRUE, FALSE, _T("DataConnPool"));
 
 
 InitializeCriticalSection(&m_csIdleConnList);
 InitializeCriticalSection(&m_csBusyConnList);
}
void DBConnPool::SetDBInfo(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)
{
 _strDBName = strDBName;
 _strDstAddress = strDstAddress;
 _strPassword = strPassword;
 _strUsername = strUsername;
  m_nMaxCount = maxConn;
  m_nMinCount = minConn;
}
DBConnPool::~DBConnPool()
{
 m_hMaintanceThread = INVALID_HANDLE_VALUE;
 m_bNeedStop = TRUE;
 CloseHandle(m_hHaveData);
 CloseHandle(m_hMaintanceThread);
 
    DeleteCriticalSection(&m_csIdleConnList);
 DeleteCriticalSection(&m_csBusyConnList);
}
DBConnPool *DBConnPool::Instanse()
{
 if (NULL == m_pInstanse)
 {
        m_pInstanse = new DBConnPool();
 }
 return m_pInstanse;
}
int DBConnPool::InitializeAllDBConnections()
{
 // 先七公里现有的数据
 DestroyAllDBConnections();
 // 开始按照最小数量开始创建
 DBConnect * pDBConnect = NULL;
 int nCount = 0;
 for (int i = 0; i < m_nMinCount; i++)
 {
  nCount = InitializeAConnection();
 }
 // 创建一个工作线程,用来进行一些后台维护工作
 if (INVALID_HANDLE_VALUE == m_hMaintanceThread)
 {
  m_hMaintanceThread = CreateThread(NULL, NULL, thread_run, (LPVOID)this, 0, NULL);
 }
 return nCount;
}
void DBConnPool::DestroyAllDBConnections()
{
 // 销毁数据库连接可以使用大锁
 EnterCriticalSection(&m_csIdleConnList);
 DBConnectList::iterator itIdle = m_listIdleConnection.begin();
 DBConnectList::iterator itIdleEnd = m_listIdleConnection.end();
 while (itIdle != itIdleEnd)
 {
  if (NULL != (*itIdle))
  {
   (*itIdle)->Close();
   delete (*itIdle);
  }
  // erase本身就会把跌代器指向下一个
  itIdle = m_listIdleConnection.erase(itIdle);
 }
 LeaveCriticalSection(&m_csIdleConnList);
 // 还有使用中的连接
 EnterCriticalSection(&m_csBusyConnList);
 DBConnectList::iterator itBusy = m_listBusyConnection.begin();
    DBConnectList::iterator itBusyEnd = m_listBusyConnection.end();
 while (itBusy != itBusyEnd)
 {
  if (NULL != (*itBusy))
  {
   (*itBusy)->Close();
   delete (*itBusy);
  }
  // erase本身就会把跌代器指向下一个
  itBusy = m_listBusyConnection.erase(itBusy);
 }
 LeaveCriticalSection(&m_csBusyConnList);
}
int DBConnPool::InitializeAConnection()
{
 BOOL bSuccess = FALSE;
 DBConnect * pDBEngine = new DBConnect(_strDstAddress, _strUsername, _strPassword, _strDBName, bSuccess);
 if (bSuccess)
 {
  m_bNeedConnection = FALSE;
  return RestoreAConnection(pDBEngine);
 }
 else
 {
  delete pDBEngine;
  return m_listIdleConnection.size();
 }
}
void DBConnPool::CloseAConnection(DBConnect* pDBEngine)
{
    pDBEngine->Close();
 // 从空闲队列将其删除
 EnterCriticalSection(&m_csIdleConnList);
 m_listIdleConnection.remove(pDBEngine);
 LeaveCriticalSection(&m_csIdleConnList);
}
DBConnect * DBConnPool::GetAConnection()
{
 DBConnect * pDBEngine = NULL;
 // 做一个循环,反复尝试五次取连接,每次间隔1秒钟
 int nTimes = 0;
 while ((m_listIdleConnection.size() <= 0) && (nTimes < 5))
 {
  Sleep(1000);
  nTimes++;
 }
 if (5 == nTimes)
 {
  // 这样狼狈的进来肯定是没有可用连接了,记录日志退出
 // g_pSvrLog->AddRunLog(LL_ERROR, _T("Waiting for a connection for a long time, but failed."));
  return pDBEngine;
 }
 // 从空闲队列中取出,并且加入到使用队列中
 EnterCriticalSection(&m_csIdleConnList);
 if (m_listIdleConnection.size() > 0)
 {
  pDBEngine = m_listIdleConnection.front();
  m_listIdleConnection.pop_front();
  // 加入使用的连接队列
  EnterCriticalSection(&m_csBusyConnList);
  m_listBusyConnection.push_back(pDBEngine);
  LeaveCriticalSection(&m_csBusyConnList);
 }
 LeaveCriticalSection(&m_csIdleConnList);
 if (m_listIdleConnection.size() <= 1)
 {
  // 剩余空闲连接的数目小于等于1个时候需要检查开始创建
  if ((m_listIdleConnection.size() + m_listBusyConnection.size()) < m_nMaxCount)
  {
   // 还小于最大限制,可以创建
   SetEvent(m_hHaveData);
   m_bNeedConnection = TRUE;
  }
  else
  {
   // 超出限制了,做个记录吧
   //g_pSvrLog->AddRunLog(LL_ERROR, _T("Database connection reached max count."));
  }
 }
 return pDBEngine;
}
int DBConnPool::RestoreAConnection(DBConnect* pDBEngine)
{
 if (NULL != pDBEngine)
 {
  // 从使用中的队列取出
  EnterCriticalSection(&m_csBusyConnList);
  m_listBusyConnection.remove(pDBEngine);
  LeaveCriticalSection(&m_csBusyConnList);
  // 加入到空闲队列中
  EnterCriticalSection(&m_csIdleConnList);
  m_listIdleConnection.push_back(pDBEngine);
  LeaveCriticalSection(&m_csIdleConnList);
 }
 EnterCriticalSection(&m_csIdleConnList);
 int nCount = m_listIdleConnection.size();
 LeaveCriticalSection(&m_csIdleConnList);
 return nCount;
}
void DBConnPool::StopThread()
{
 m_bNeedStop = TRUE;
 // 因为线程是无限制等待信号的,所以这里先把标志位置为停止,然后发信号让线程检测
 SetEvent(m_hHaveData);
 // 等待退出
 WaitForSingleObject(m_hMaintanceThread, INFINITE);
 CloseHandle(m_hMaintanceThread);
}
BOOL DBConnPool::IsNeedStop()
{
 return m_bNeedStop;
}
BOOL DBConnPool::IsNeedConnection()
{
 return m_bNeedConnection;
}
/************************************************************************/
/* 维护线程                                                             */
/************************************************************************/
DWORD WINAPI DBConnPool::thread_run( LPVOID pdata)
{
 DBConnPool * pConPool = (DBConnPool *) pdata;
 while (!pConPool->IsNeedStop())
 {
  // 设置事件为无信号, 并且无限制等待
  ResetEvent(pConPool->m_hHaveData);  
  WaitForSingleObject(pConPool->m_hHaveData, INFINITE);
  if (pConPool->IsNeedConnection())
  {
  // g_pSvrLog->AddRunLog(LL_DEBUG, _T("Create a new DB connection."));
   pConPool->InitializeAConnection();
  }
 }
 return 0;
}
 

为了使用方便,使用的时候,自己定义个类来初始化连接以及所使用的接口,

例如,,定义个DBinterface的类

头文件中这样写

view plaincopy to clipboardprint?
01.// DBInterface.h: interface for the DBInterface class.   
02.//   
03.//   
04.#if !defined(AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_)   
05.#define AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_   
06.#if _MSC_VER > 1000   
07.#pragma once   
08.#endif // _MSC_VER > 1000   
09.#include "DBDefine.h"   
10.#include "DBConnPool.h"   
11.#if defined(__cplusplus)   
12.extern "C"  
13.{   
14.#endif   
15.       
16.    // Initialize RS Receiver   
17.    RFIDAPI DWORD  InItDBConnPool(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);   
18.    RFIDAPI void   GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms);   
19.    RFIDAPI void   InsertHistory(int id);   
20.    RFIDAPI int    UserLogin(LPCSTR name,LPCSTR password);   
21.       
22.    // Initialize Sock Receiver   
23.       
24.#if defined(__cplusplus)   
25.}   
26.#endif   
27.#endif // !defined(AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_)  
// DBInterface.h: interface for the DBInterface class.
//
//
#if !defined(AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_)
#define AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "DBDefine.h"
#include "DBConnPool.h"
#if defined(__cplusplus)
extern "C"
{
#endif
 
 // Initialize RS Receiver
 RFIDAPI DWORD  InItDBConnPool(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn);
 RFIDAPI void   GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms);
 RFIDAPI void   InsertHistory(int id);
 RFIDAPI int    UserLogin(LPCSTR name,LPCSTR password);
 
 // Initialize Sock Receiver
 
#if defined(__cplusplus)
}
#endif
#endif // !defined(AFX_DBINTERFACE_H__E761F9FE_39EE_40A2_88D1_7FCBB97A145A__INCLUDED_)
 

实现文件如下

view plaincopy to clipboardprint?
01.// DBInterface.cpp : Defines the entry point for the DLL application.   
02.//                                                             */   
03./************************************************************************/  
04.#include "stdafx.h"   
05.#include "DBInterface.h"   
06.DWORD InItDBConnPool(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)   
07.{   
08.    DBConnPool::Instanse()->SetDBInfo(strDstAddress,strUsername,strPassword,strDBName,minConn,maxConn);   
09.    return DBConnPool::Instanse()->InitializeAllDBConnections();   
10.}   
11.void GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms)   
12.{   
13.    DBConnect *pDBConn = NULL;   
14.    DBConnGuard oConnGuard(pDBConn);   
15.    pDBConn->GetSubmitInfo(vecsoapSms);   
16.}   
17.void InsertHistory(int id)   
18.{   
19.    DBConnect *pDBConn = NULL;   
20.    DBConnGuard oConnGuard(pDBConn);   
21.    pDBConn->InsertHistory(id);   
22.}   
23.int UserLogin(LPCSTR name,LPCSTR password)   
24.{   
25.    DBConnect *pDBConn = NULL;   
26.    DBConnGuard oConnGuard(pDBConn);   
27.    return  pDBConn->UserLogin(name,password);   
28.}  
// DBInterface.cpp : Defines the entry point for the DLL application.
//                                                             */
/************************************************************************/
#include "stdafx.h"
#include "DBInterface.h"
DWORD InItDBConnPool(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)
{
 DBConnPool::Instanse()->SetDBInfo(strDstAddress,strUsername,strPassword,strDBName,minConn,maxConn);
 return DBConnPool::Instanse()->InitializeAllDBConnections();
}
void GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms)
{
 DBConnect *pDBConn = NULL;
 DBConnGuard oConnGuard(pDBConn);
 pDBConn->GetSubmitInfo(vecsoapSms);
}
void InsertHistory(int id)
{
 DBConnect *pDBConn = NULL;
 DBConnGuard oConnGuard(pDBConn);
 pDBConn->InsertHistory(id);
}
int UserLogin(LPCSTR name,LPCSTR password)
{
 DBConnect *pDBConn = NULL;
 DBConnGuard oConnGuard(pDBConn);
    return pDBConn->UserLogin(name,password);
}

这样把头文件包含到工程,,

调用InItDBConnPool初始化连接池

然后就可以直接使用接口了

转载于:https://my.oschina.net/laopiao/blog/103756

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值