1. 程式人生 > >資料庫MySql類庫系列(八)-預處理執行Sql方式的示例

資料庫MySql類庫系列(八)-預處理執行Sql方式的示例

本文是對之前預處理執行Sql方式的示例程式TestDB

首先是資料表定義:

還是一個簡單的賬號表,包括3個欄位:帳號名(最長20個字元,主鍵),賬號密碼(最長20個字元),賬號id(無符號整數,自增欄位)

sql如下:

CREATE TABLE `account` (
  `account_name` varchar(20) NOT NULL,
  `account_key` varchar(20) NOT NULL,
  `account_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`account_name`),
  UNIQUE KEY `account_id_index` (`account_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

下面演示對這張表,以預處理執行sql的方式,實現增、刪、改、查

首先,實現一個PrepareDBService,繼承DBService

實現4個介面:

	
// 分別實現增、刪、改、查
bool SelectAccount(const char(&name)[MaxAccountLen], char(&key)[MaxAccountLen], unsigned int& id);
bool InsertAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen]);
bool UpdateAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen]);
bool DeleteAccount(const char(&name)[MaxAccountLen]);

對應4個操作物件(2種:增刪改對應PrepareOperatorUpdate,查詢對應PrepareOperatorSelect)

// 對應增、刪、改、查四種操作的預處理的繫結引數/繫結結果
void PrepareSelectAccount();
void PrepareInsertAccount();
void PrepareUpdateAccount();
void PrepareDeleteAccount();
	
// 對應增、刪、改、查四種操作物件
common::db::PrepareOperatorSelect m_select_account;
common::db::PrepareOperatorUpdate m_insert_account;
common::db::PrepareOperatorUpdate m_update_account;
common::db::PrepareOperatorUpdate m_delete_account;

主要的類關係圖如下:


主函式:

1、插入一個賬號,賬號名=Test001,密碼=0000001的賬號

2、更新這個賬號的密碼,改為1111111

3、查詢這個賬號名=Test001的賬號資訊(賬號名,密碼,id),此時密碼應為第2步已經修改後的密碼,如果該表此前沒有插入過記錄,此時id應該為1,每執行一次插入id+1

4、刪除這個賬號名=Test001的賬號

5、再次查詢這個賬號名=Test001的賬號資訊,此時應該沒有對應的資料

執行結果截圖:


DBService的子類實現:

PrepareDBService.h:

#ifndef __PrepareDBService_H__
#define	__PrepareDBService_H__

#include "DBService.h"

#include "PrepareOperatorSelect.h"
#include "PrepareOperatorUpdate.h"

class PrepareDBService : public common::db::DBService
{
public:
	PrepareDBService();
	virtual ~PrepareDBService();

public:
	// 最大賬號,密碼字串長度為20個字元
	static const unsigned int MaxAccountLen = 20;

public:
	virtual bool ProcessStart();

	virtual void ProcessStop();

	// 分別實現增、刪、改、查
	bool SelectAccount(const char(&name)[MaxAccountLen], char(&key)[MaxAccountLen], unsigned int& id);
	bool InsertAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen]);
	bool UpdateAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen]);
	bool DeleteAccount(const char(&name)[MaxAccountLen]);

private:
	// 賬號屬性型別
	enum AccountPropertyType
	{
		account_name = 0,		// 帳號名稱
		account_key,			// 賬號密碼
		account_id,				// 賬號id

		account_property_count,
	};
	unsigned long m_property_len[account_property_count];
	void InitPropertyLen();

	// 賬號資訊繫結值
	char m_account_name[MaxAccountLen];
	char m_account_key[MaxAccountLen];
	unsigned int m_account_id;

	// 各個預處理的繫結引數/繫結結果
	void PrepareSelectAccount();
	void PrepareInsertAccount();
	void PrepareUpdateAccount();
	void PrepareDeleteAccount();

	// 對應增、刪、改、查四種操作物件
	common::db::PrepareOperatorSelect m_select_account;
	common::db::PrepareOperatorUpdate m_insert_account;
	common::db::PrepareOperatorUpdate m_update_account;
	common::db::PrepareOperatorUpdate m_delete_account;
};

#endif


PrepareDBService.cpp:

#include "PrepareDBService.h"

PrepareDBService::PrepareDBService()
{

}

PrepareDBService::~PrepareDBService()
{

}

bool PrepareDBService::ProcessStart()
{
	//預處理sql
	InitPropertyLen();

	PrepareSelectAccount();
	PrepareInsertAccount();
	PrepareUpdateAccount();
	PrepareDeleteAccount();

	return true;
}

void PrepareDBService::ProcessStop()
{
	m_select_account.Release();
	m_insert_account.Release();
	m_update_account.Release();
	m_delete_account.Release();
}

void PrepareDBService::InitPropertyLen()
{
	m_property_len[account_name] = sizeof(m_account_name);
	m_property_len[account_key] = sizeof(m_account_key);
	m_property_len[account_id] = sizeof(m_account_id);
}

void PrepareDBService::PrepareSelectAccount()
{
	//預處理sql
	m_select_account.BindSql(m_Connect,
		"select * from account where account_name = ?;");

	m_select_account.BindResult("%s,%s,%u",
		m_account_name, &m_property_len[account_name],
		m_account_key, &m_property_len[account_key],
		&m_account_id);

	m_select_account.BindParameter("%s",
		m_account_name, &m_property_len[account_name]);
}

bool PrepareDBService::SelectAccount(const char(&name)[MaxAccountLen], char(&key)[MaxAccountLen], unsigned int& id)
{
	boost::mutex::scoped_lock lock(m_Lock);

	strcpy(m_account_name, name);

	if (m_select_account.DoOperator())
	{
		if (m_select_account.FetchResult())
		{
			strcpy(key, m_account_key);
			id = m_account_id;

			m_select_account.FreeResult();

			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

void PrepareDBService::PrepareInsertAccount()
{
	m_insert_account.BindSql(m_Connect,
		"insert into account(account_name, account_key) values(?, ?);");

	m_insert_account.BindParameter("%s,%s",
		m_account_name, &m_property_len[account_name],
		m_account_key, &m_property_len[account_key]);
}

bool PrepareDBService::InsertAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen])
{
	boost::mutex::scoped_lock lock(m_Lock);

	strcpy(m_account_name, name);
	strcpy(m_account_key, key);

	return m_insert_account.DoOperator();
}

void PrepareDBService::PrepareUpdateAccount()
{
	m_update_account.BindSql(m_Connect,
		"update account set account_key = ? where account_name = ?;");

	m_update_account.BindParameter("%s,%s",
		m_account_key, &m_property_len[account_key],
		m_account_name, &m_property_len[account_name]);
}

bool PrepareDBService::UpdateAccount(const char(&name)[MaxAccountLen], const char(&key)[MaxAccountLen])
{
	boost::mutex::scoped_lock lock(m_Lock);

	strcpy(m_account_name, name);
	strcpy(m_account_key, key);

	return m_update_account.DoOperator();
}

void PrepareDBService::PrepareDeleteAccount()
{
	m_delete_account.BindSql(m_Connect,
		"delete from account where account_name = ?;");

	m_delete_account.BindParameter("%s",
		m_account_name, &m_property_len[account_name]);
}

bool PrepareDBService::DeleteAccount(const char(&name)[MaxAccountLen])
{
	boost::mutex::scoped_lock lock(m_Lock);

	strcpy(m_account_name, name);

	return m_delete_account.DoOperator();
}


主函式TestDB.cpp:

#include <iostream>

#include "PrepareDBService.h"

void PrepareAccount()
{
	char accountName[PrepareDBService::MaxAccountLen] = { 0 };
	char accountKey[PrepareDBService::MaxAccountLen] = { 0 };
	unsigned int accountId = 0;

	PrepareDBService service;
	service.Start("127.0.0.1", 3306, "root", "root", "account");

	/////////////////////////Insert/////////////////////////
	memset(accountName, 0x00, sizeof(accountName));
	strcpy(accountName, "Test001");
	memset(accountKey, 0x00, sizeof(accountKey));
	strcpy(accountKey, "0000001");
	if (service.InsertAccount(accountName, accountKey))
	{
		std::cout << "InsertAccount name = " << accountName << ", key = " << accountKey << " success" << std::endl;
	}

	/////////////////////////Update/////////////////////////
	memset(accountName, 0x00, sizeof(accountName));
	strcpy(accountName, "Test001");
	memset(accountKey, 0x00, sizeof(accountKey));
	strcpy(accountKey, "1111111");
	if (service.UpdateAccount(accountName, accountKey))
	{
		std::cout << "UpdateAccount name = " << accountName << ", key = " << accountKey << " success" << std::endl;
	}

	/////////////////////////Select/////////////////////////
	memset(accountName, 0x00, sizeof(accountName));
	strcpy(accountName, "Test001");
	if (service.SelectAccount(accountName, accountKey, accountId))
	{
		std::cout << "SelectAccount name = " << accountName << ", key = " << accountKey << " , id = " << accountId << std::endl;
	}
	else
	{
		std::cout << "no result" << std::endl;
	}

	/////////////////////////Delete/////////////////////////
	memset(accountName, 0x00, sizeof(accountName));
	strcpy(accountName, "Test001");
	if (service.DeleteAccount(accountName))
	{
		std::cout << "DeleteAccount name = " << accountName << " success" << std::endl;
	}

	/////////////////////////Select/////////////////////////
	memset(accountName, 0x00, sizeof(accountName));
	strcpy(accountName, "Test001");
	if (service.SelectAccount(accountName, accountKey, accountId))
	{
		std::cout << "SelectAccount name = " << accountName << ", key = " << accountKey << " , id = " << accountId << std::endl;
	}
	else
	{
		std::cout << "no result" << std::endl;
	}

	service.Stop();
}

int main(int argc, char* argv[])
{
	PrepareAccount();

	system("pause");

	return 0;
}