어떻게 C++를 이용 하여 my sql 데이터 베 이 스 를 연결 하 는 지 상세 하 게 설명 합 니 다.
현재 거의 모든 배경 응용 은 데이터 베 이 스 를 사용 하고 어떤 관계 형,비 관계 형 을 사용 해 야 합 니까?정당한 관계 의,부당 한 관계 의;주류 와 비주류,크게 는 Oracle,작 게 는 sqlite,그리고 현재 점차적으로 유행 하고 있 는 사물 인터넷 을 바탕 으로 하 는 순차 데이터 베 이 스 를 포함한다.예 를 들 어 타 오 스 의TDengine,우리 중국인 들 의 오픈 소스 순차 데이터 베이스,성능 지렛대 방울 이다.
이 모든 것 은 사용 해 본 적 이 없어 도 들 어 본 적 이 있 지만 대부분 사람들 이나 기업 에서 가장 많이 사용 하 는 것 은 바로 오입쟁이 형 데이터 베이스:my sql 이다.이 데이터 베 이 스 는 개인 이 든 기업 이 든 모두 할 수 있 는 것 이 특징 이다.Oracle 과 같은 명 원 형 데이터 베 이 스 는 기본적으로 은행 특 공 에 속 하기 때문에 은행 은 돈 을 써 서 평안 을 사 야 하고 마음 이 든든 하 다.맞 는 것 은 사지 않 고 비 싼 것 만 선택한다.왜냐하면 남 들 은 확실히 돈 이 모자 라 지 않 기 때문이다.
만약 당신 의 백 스테이지 응용 이 데이터베이스 도 필요 하지 않다 면,소금 에 절 인 생선 사이트 와 어떤 차이 가 있 습 니까?소금 에 절 인 생선 중고 망 도 데이터 베 이 스 를 사용 해 야 한다.만약 IT 노동자 가 평생 데이터 베 이 스 를 사용 하지 않 고 35(~45)세 에'퇴직 당 했다'면 그의 직업 생활 은 유감 이 고 완벽 하지 않 으 며 순수 하지 않다.어쨌든 젊 으 면 비주류 액 세 스 를 써 야 지,엑 세 셀 이라도.이런 느낌 은 마치 대학 때 연 애 를 해 본 적 이 없 는 것 처럼 남 을 부러워 하 느 라 바 빠 서 갑자기 졸업 한 것 과 같다.
왜 자원 탱크 를 만 들 려 고 합 니까?
현재 대부분의 백 엔 드 프로그램 은 자바 개발 이나 PHP 를 선택 하고 있 으 며,이 두 언어의 제3자 라 이브 러 리 는 개발 자 들 이 구체 적 인 업무 에 만 신경 을 쓰 면 될 정도 로 풍부 하 다.예 를 들 어 데이터 뱅 크 의 자원 탱크 는 적당 한 jar 가방 을 선택 하고 해당 하 는 데이터 베 이 스 를 설정 하면 안심 하고 대담 하 게 my sql 을 사용 할 수 있 습 니 다.
물론 팔자 가 세다 면 C 나 C++로 백 엔 드 애플 리 케 이 션 을 개발 할 수도 있다.이 럴 때 는 스스로 DIY 데이터베이스 자원 탱크 가 필요 하 다.
만약 에 하나의 클 라 이언 트 프로그램 이 라면 연결 탱크 가 필요 하지 않 지만 배경 응용 에 있어 높 은 병행 은 다 중 스 레 드 를 의미 하고 다 중 스 레 드 는 자원 의 경쟁 을 의미한다.메모리 접근 도 그 렇 고 데이터베이스 접근 도 마찬가지다.매번 데이터 베 이 스 를 열 고 닫 는 것 은 네트워크 연결 과 닫 는 과정 으로 빈번 한 열 고 닫 는 것 은 의심 할 여지없이 대량의 시스템 자원 을 낭비 할 것 이다.이 럴 때 는 N 개의 연결 을 미리 만들어 자원 탱크 에 넣 고 서로 다른 스 레 드 에 접근 할 수 있 도록 제공 해 야 합 니 다.
mysql 자원 탱크 구현 사례 원본
나 는 좋 은 코드 는 지나 치지 않 는 언어 로 설명 할 필요 가 없다 고 믿 어 왔 다.코드 즉 문서,어떤 자전 거 를 원 하 는 지.아래 의 사례 는 단지 실현 사고 일 뿐 이 니 참고 하 시기 바 랍 니 다.
헤더 파일:MysqlPool.h
#pragma warning(disable : 4786)
#include <windows.h>
#include <winsock2.h>
#include <mysql.h> // mysql
#include <vector>
#include <string>
using namespace std;
#define DEFAULT_POOL_SIZE 20 // mysql
#define DEFAULT_POOL_TIMEOUT 60 // mysql
//
typedef BOOL (CALLBACK *LPFN_RetrieveRecordData)(MYSQL_ROW& sqlRow, MYSQL_FIELD* pSqlFields, int iFieldCount, DWORD dwUserData);
// Mysql
class CMysqlConn
{
public:
CMysqlConn(const char* pszDBServer, UINT uDBPort, const char* pszDBName,
const char* pszDBUser, const char* pszDBPwd);
virtual ~CMysqlConn();
public:
// / mysql
BOOL Open();
void Close();
// ping
BOOL Ping();
//
BOOL ResetCharset();
public:
// ================SQL ( )================
//
BOOL Select(const char* pszSql, LPFN_RetrieveRecordData lpfnRetrieveRecordData, DWORD dwUserData);
//
BOOL Execute(const char* pszSql);
// , ,
__int64 Insert(const char* pszSql);
protected:
MYSQL* m_pMysql; // mysql
// mysql
string m_strDBServer; // mysql
UINT m_uDBPort; // mysql
string m_strDBName; //
string m_strDBUser; //
string m_strDBPwd; //
};
//
class CMysqlPool
{
public:
CMysqlPool();
virtual ~CMysqlPool();
// mysql
BOOL Create(const char* pszDBServer, UINT uDBPort, const char* pszDBName,
const char* pszDBUser, const char* pszDBPwd,
DWORD dwPoolSize = DEFAULT_POOL_SIZE,
DWORD dwTimeOut = DEFAULT_POOL_TIMEOUT);
//
void Destroy();
public:
// mysql
CMysqlConn* Get();
// mysql
void Release(CMysqlConn* pConn);
protected:
HANDLE m_hSemaphore; //
DWORD m_dwPoolSize; //
DWORD m_dwTimeOut; // ,
CRITICAL_SECTION m_csPool; //
vector<CMysqlConn*> m_vecIdle; //
vector<CMysqlConn*> m_vecBusy; //
};
구현 파일:MysqlPool.cpp
#include "stdafx.h"
#include "MysqlPool.h"
#include <assert.h>
#include <algorithm>
#pragma comment(lib, "libmysql.lib") // MysQL
//////////////////////////////////////////////////////////////////////
// CMysqlConn: mysql
//////////////////////////////////////////////////////////////////////
CMysqlConn::CMysqlConn(const char* pszDBServer, UINT uDBPort, const char* pszDBName,
const char* pszDBUser, const char* pszDBPwd)
{
assert(pszDBServer);
assert(pszDBName);
assert(pszDBUser);
assert(pszDBPwd);
m_pMysql = NULL;
m_strDBServer = pszDBServer;
m_uDBPort = uDBPort;
m_strDBName = pszDBName;
m_strDBUser = pszDBUser;
m_strDBPwd = pszDBPwd;
}
CMysqlConn::~CMysqlConn()
{
Close();
}
// mysql ,
BOOL CMysqlConn::Open()
{
if(m_pMysql)
{
mysql_close(m_pMysql); //
m_pMysql = NULL;
}
m_pMysql = mysql_init(NULL);
if(!m_pMysql)
return FALSE;
//
if(!mysql_real_connect(m_pMysql, m_strDBServer.c_str(), m_strDBUser.c_str(),
m_strDBPwd.c_str(), m_strDBName.c_str(), m_uDBPort, NULL, 0))
{
int i = mysql_errno(m_pMysql);
const char * pszErr = mysql_error(m_pMysql);
return FALSE;
}
//
char chValue = 1;
mysql_options(m_pMysql, MYSQL_OPT_RECONNECT, &chValue);
mysql_query(m_pMysql,"set names 'gbk'");
return TRUE;
}
//
void CMysqlConn::Close()
{
if(m_pMysql)
mysql_close(m_pMysql); //
m_pMysql = NULL;
}
// ping mysql,
BOOL CMysqlConn::Ping()
{
if(m_pMysql)
return (0 == mysql_ping(m_pMysql));
return FALSE;
}
// GBK
BOOL CMysqlConn::ResetCharset()
{
if(m_pMysql)
return (0 == mysql_query(m_pMysql, "set names 'gbk'"));
return FALSE;
}
// mysql :delete update
BOOL CMysqlConn::Execute(const char* pszSql)
{
assert(pszSql);
if(!m_pMysql)
return FALSE;
MYSQL_STMT *myStmt = mysql_stmt_init(m_pMysql);
if(!myStmt)
{
return FALSE;
}
if(0 != mysql_stmt_prepare(myStmt, pszSql, strlen(pszSql)))
{
mysql_stmt_close(myStmt);
return FALSE;
}
if(0 != mysql_stmt_execute(myStmt))
{
mysql_stmt_close(myStmt);
return FALSE;
}
mysql_stmt_close(myStmt);
return TRUE;
}
// mysql
__int64 CMysqlConn::Insert(const char* pszSql)
{
assert(pszSql);
MYSQL_STMT *myStmt = mysql_stmt_init(m_pMysql);
if(!myStmt)
return 0;
if(0 != mysql_stmt_prepare(myStmt, pszSql, strlen(pszSql)))
{
int i = mysql_errno(m_pMysql);
const char * s = mysql_error(m_pMysql);
mysql_stmt_close(myStmt);
return 0;
}
if(0 != mysql_stmt_execute(myStmt))
{
mysql_stmt_close(myStmt);
return 0;
}
mysql_stmt_close(myStmt);
__int64 i64ID = mysql_insert_id(m_pMysql);
return i64ID;
}
// mysql
BOOL CMysqlConn::Select(const char* pszSql, LPFN_RetrieveRecordData lpfnRetrieveRecordData, DWORD dwUserData)
{
if(!m_pMysql)
return FALSE;
if(NULL == lpfnRetrieveRecordData)
return FALSE;
if(0 != mysql_real_query(m_pMysql, pszSql, strlen(pszSql)))
{
return FALSE;
}
MYSQL_RES *resRecord = mysql_store_result(m_pMysql);
int iFieldCount = resRecord->field_count;
MYSQL_ROW sqlRow;
while (sqlRow = mysql_fetch_row(resRecord))
{
if(!lpfnRetrieveRecordData(sqlRow, resRecord->fields, iFieldCount, dwUserData))
break;
}
mysql_free_result(resRecord);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CMysqlPool: mysql
//////////////////////////////////////////////////////////////////////
CMysqlPool::CMysqlPool()
{
::InitializeCriticalSection(&m_csPool);
}
CMysqlPool::~CMysqlPool()
{
Destroy();
::DeleteCriticalSection(&m_csPool);
}
// mysql
BOOL CMysqlPool::Create(const char* pszDBServer, UINT uDBPort, const char* pszDBName,
const char* pszDBUser, const char* pszDBPwd,
DWORD dwPoolSize, DWORD dwTimeOut)
{
m_dwTimeOut = dwTimeOut;
m_dwPoolSize = dwPoolSize;
//
m_hSemaphore = ::CreateSemaphore(NULL, dwPoolSize, dwPoolSize, NULL);
if (NULL == m_hSemaphore)
{
return FALSE;
}
//
for(DWORD i = 0; i < dwPoolSize; ++i)
{
// mysql
CMysqlConn *pConn = new CMysqlConn(pszDBServer, uDBPort, pszDBName, pszDBUser, pszDBPwd);
if(!pConn->Open())
{
delete pConn;
continue;
}
m_vecIdle.push_back(pConn);
}
return m_vecIdle.size() > 0;
}
// mysql
void CMysqlPool::Destroy()
{
::CloseHandle(m_hSemaphore);
m_hSemaphore = NULL;
// idle
vector<CMysqlConn*>::iterator it;
for(it = m_vecIdle.begin(); it != m_vecIdle.end(); ++it)
{
CMysqlConn* pConn = *it;
delete pConn;
}
m_vecIdle.clear();
// busy
while(!m_vecBusy.empty())
{
CMysqlConn* pConn = m_vecBusy.back();
m_vecBusy.pop_back();
delete pConn;
}
}
// mysql
CMysqlConn* CMysqlPool::Get()
{
DWORD dwRet = ::WaitForSingleObject(m_hSemaphore, m_dwTimeOut*1000);
if (WAIT_OBJECT_0 != dwRet) // , mysql
{
printf(" 。\r
");
return NULL;
}
//
CMysqlConn* pConn = NULL;
::EnterCriticalSection(&m_csPool);
if (!m_vecIdle.empty())
{
pConn = m_vecIdle.back(); // idle
m_vecIdle.pop_back();
m_vecBusy.push_back(pConn); // busy
}
::LeaveCriticalSection(&m_csPool);
if(NULL == pConn)
return NULL;
// , , mysql_ping
//
// ,
if(!pConn->ResetCharset())
{
if(!pConn->Open())
return NULL;
}
printf("==》 : 。\r
");
return pConn;
}
// mysql
void CMysqlPool::Release(CMysqlConn* pConn)
{
if(NULL == pConn)
return;
//
::ReleaseSemaphore(m_hSemaphore, 1, NULL);
::EnterCriticalSection(&m_csPool);
// Busy
vector<CMysqlConn*>::iterator it = find(m_vecBusy.begin(), m_vecBusy.end(), pConn);
if(it != m_vecBusy.end())
{
printf("POOL SIZE : %d, %d\r
", m_vecIdle.size(), m_vecBusy.size());
m_vecBusy.erase(it); // busy
m_vecIdle.push_back(pConn); // idle
printf("POOL SIZE : %d, %d\r
", m_vecIdle.size(), m_vecBusy.size());
}
::LeaveCriticalSection(&m_csPool);
printf("《== : , 。\r
");
}
테스트 함수
void TestMysqlPool()
{
// mysql
CMysqlPool mysqlPool;
if(!mysqlPool.Create("127.0.0.1", 3306, "information_schema", "root", "123456"))
{
printf("Create mysql conneticon pool failed.\r
");
return;
}
// , : !
CMysqlConn* pConn = mysqlPool.Get();
//
char* pszSQL = "SELECT * FROM CHARACTER_SETS";
pConn->Select(pszSQL, RetrieveRecordData, 0);
// ! : !
mysqlPool.Release(pConn);
printf("Test over.\r
");
}
출력 인쇄총결산
C++를 이용 하여 my sql 데이터베이스 연결 풀 을 어떻게 실현 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++my sql 연결 풀 을 실현 하 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.