精简且可扩展的 mySQL C++ 包装器






3.76/5 (9投票s)
2007 年 2 月 26 日
1分钟阅读

45634

2033
一篇关于提供 mySQL 查询的精简(
引言
本文介绍了一个精简的 MySQL C++ 封装。所有函数都定义在两个头文件中。用户可以使用 MySQL C API 库和 boost::shared_ptr
的头文件来构建该文件,boost::shared_ptr
用于管理 MySQL 连接和结果集。
使用代码
MySQL 客户端封装的类图如下所示。
结构非常简单。唯一需要注意的特殊成员函数是 CMysqlConn::Query
。该函数有一个模板参数 'ProcessQuery
',这是一个 'policy
' 类,用于处理 API 的具体客户端需求。不同的客户端查询数据库的目的不同。有些客户端想要获取满足特定条件的数据。有些客户端想要插入和更新记录,不需要返回数据。其他客户端可能只想获取满足给定 'where' 子句的数据的 ID 类型。受到 Andrei Alexandrescu 的 "Modern C++ design" 中提出的基于策略的解决方案的启发,'Query
' 成员函数使用模板解决方案将使用策略与通用查询算法分离。
我已经为 CMysqlConn::Query
定义了三个策略类。以下是使用场景。
- 需要返回数据的数据库查询
CMysqlSet rset=conn.Query<WithData>("select * from mytable");
- 不需要返回数据的数据库查询
bool ret =conn.Query<NoData>("insert into mytable values (5000, 'testing message')");
- 仅获取单个值的数据库查询
pair<bool, string> value=conn.Query<CheckOneRecord> ("select field from mytable where errorcode='2005'");
用户可以通过遵循此示例定义自己的策略类
struct Nodata
{
//Define your return type
typedef boolReturnType;
//Define your failed return function for the query failure case
static ReturnType ReturnInFail() {return false;}
//Define your records processing implementation after the
//query statement is successfully issued.
static ReturnType DeepQuery(ConnPtr ptr) {return true;}
};
以下是使用此封装的示例代码
int Test()
{
string query="select * from mytable";
CMysqlConn conn("myhost","mytable", "login","password");
if (conn)
{
CMysqlSet rset=conn.Query<WithData>(query);
if (rset)
{
cout<<"I got a result";
unsigned size=rset.NumberOfRecords();
for (unsigned int i=0;i<size; i++){
CMysqlRow row=rset.GetNextRow();
if (row)
{
for (unsigned int j=0; j<row.NumberOfFields();j++)
{
cout<<row[j];
}
cout<<endl;
}
}
}
cout<<"Last error is
"<<conn.GetLastfiled1()<<":"<<conn.GetLastErrorString()<<endl;
string updateQuery="insert into mytable values (5000, 'testing message')";
conn.Query<NoData>(updateQuery);
//
// Query single data test
//
cout<<"query single data..."<<endl;
pair<bool, string> value=conn.Query<CheckOneRecord>
("select filed1s from mytable where filed1='2005'");
if (value.first)
{
cout<<"get value of "<<value.second<<endl;
}
}
return 0;
}