65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.76/5 (9投票s)

2007 年 2 月 26 日

1分钟阅读

viewsIcon

45634

downloadIcon

2033

一篇关于提供 mySQL 查询的精简( 2 个头文件) C++ 模板类的文章

引言

本文介绍了一个精简的 MySQL C++ 封装。所有函数都定义在两个头文件中。用户可以使用 MySQL C API 库和 boost::shared_ptr 的头文件来构建该文件,boost::shared_ptr 用于管理 MySQL 连接和结果集。

使用代码

MySQL 客户端封装的类图如下所示。

Screenshot - mysql_simple_wrapper_1.jpg

结构非常简单。唯一需要注意的特殊成员函数是 CMysqlConn::Query。该函数有一个模板参数 'ProcessQuery',这是一个 'policy' 类,用于处理 API 的具体客户端需求。不同的客户端查询数据库的目的不同。有些客户端想要获取满足特定条件的数据。有些客户端想要插入和更新记录,不需要返回数据。其他客户端可能只想获取满足给定 'where' 子句的数据的 ID 类型。受到 Andrei Alexandrescu 的 "Modern C++ design" 中提出的基于策略的解决方案的启发,'Query' 成员函数使用模板解决方案将使用策略与通用查询算法分离。

我已经为 CMysqlConn::Query 定义了三个策略类。以下是使用场景。

  1. 需要返回数据的数据库查询

    CMysqlSet rset=conn.Query<WithData>("select * from mytable");

  2. 不需要返回数据的数据库查询

    bool ret =conn.Query<NoData>("insert into mytable values 
                        (5000, 'testing message')");

  3. 仅获取单个值的数据库查询

    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;
}
© . All rights reserved.