zoukankan      html  css  js  c++  java
  • Mysql++学习(三)------举个栗子

    下面例子显示了如何建立利用Sql++建立一个连接,执行查询操作,返回一个结果集,并且打印.

     1 #include <iostream>
     2 #include <mysql++.h>
     3 #include <errno.h>
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 
     7 using namespace std;
     8 
     9 int main()
    10 {
    11     mysqlpp::Connection conn(false);
    12     //connect to the database
    13     if(conn.connect("mysql_cpp_data", "127.0.0.1", "comoon", ""))
    14     {
    15         //execute a query
    16         mysqlpp::Query query = conn.query("select * from stock");
    17         //get query result in a storeResult
    18         mysqlpp::StoreQueryResult res = query.store();
    19         if(res)
    20         {
    21             for(size_t i = 0; i < res.num_rows(); i++)
    22             {
    23                 cout << setw(20) << res[i]["item"] <<
    24                         setw(10) << res[i]["num"] <<
    25                         setw(10) << res[i]["weight"] <<
    26                         setw(10) << res[i]["price"] <<
    27                         setw(10) << res[i]["sdate"] <<
    28                         endl;
    29             }
    30         }
    31         else
    32         {
    33             perror("Failed to get data!");
    34             exit(EXIT_FAILURE);
    35         }
    36     }
    37     else
    38     {
    39         perror("Connect Failed");
    40         exit(EXIT_FAILURE);
    41     }
    42     return 0;
    43 }

    异常

    默认情况下,MySql++使用异常来通知错误,通过给connection的构建函数传递参数,来确定是否要开启异常处理,前面例子中使用false来关闭了异常,在一个正常程序中建议开启异常处理。

    所有MySql++的常规异常,都继承自类Exception.而该类继承自标准C++的std::exception类.所以,仅仅通过捕获std::exception,就可以捕获和处理一切异常。不过,还是建议对于具体的异常采用捕获代码块。

     当异常处理被关闭的时候,MySql++通过返回错误代码,或者尝试失败的对象,或设置对象的错误标识来通知错误。继承自OptionalExcetions接口的对象允许你关闭异常,当一个OptionalExcetions衍生类创建了也继承自该接口的对象时,它也会传递异常标识。因为一切都源于connection对象,所以,在开始的时候关闭connection上的异常就会关闭所有OptionalExcetions。

    也可以在一个代码块中关闭异常处理,你可以在代码开始地方创建一个NoExceptions对象,来防止代码块抛出异常。当它被创建之后,它会记录下传递过来的异常标识,在代码执行结束后,它将恢复异常标识到之前的状态。

    mysqlpp::Connection con; // default ctor, so exceptions enabled
    
    {
      mysqlpp::NoExceptions ne(con);
      if (!con.select_db("a_db_that_might_not_exist_yet")) {
        // Our DB doesn’t exist yet, so create and select it here; no need
        // to push handling of this case way off in an exception handler.
      }
    }

    查询操作

    MySql++支持三种查询: Query::execute()Query::store()和 Query::use()

    execute()用于不返回数据的查询.例如执行CREATE INDEX,你并没有从服务器获取数据,程序将返回一个SimpleResult对象,以及一个标识执行成功与否的标识,该对象还包含命令执行所影响的行数,如果只要成功与否的标识,可以使用Query::exec(),其返回结果为bool.

    如果你的查询需要从服务器拉数据,那么可以简单使用store().它将返回一个StoreQueryResult对象,该对象包含整个结果集,这将非常简单,因为StoreQueryResult 继承自std::vector<mysqlpp::Row>,它包含STL的各种操作.

    如果你想将返回的结果集存在一个非vector的标准容器中,你可以使用Query::storein().

    store*()查询可能很方便,但是,将整个结果集全部存储在内存中,代价可能会很大.事实上,MySql数据库服务器将数据压缩存储在硬盘上,但是返回给客户端的是文本形式.对于很大的返回结果集,最好使用use()查询.它返回一个UseQueryResult.该对象类似StoreQueryResult,但是不提供随机访问的特性.use查询会让服务器一次返回结果集的一行,进分行处理.

     if (mysqlpp::UseQueryResult res = query.use()) {
                // Display header
                cout.setf(ios::left);
                cout << setw(31) << "Item" <<
                        setw(10) << "Num" <<
                        setw(10) << "Weight" <<
                        setw(10) << "Price" <<
                        "Date" << endl << endl;
    
                // Get each row in result set, and print its contents
                while (mysqlpp::Row row = res.fetch_row()) {
                    cout << setw(30) << row["item"] << ' ' <<
                            setw(9) << row["num"] << ' ' <<
                            setw(9) << row["weight"] << ' ' <<
                            setw(9) << row["price"] << ' ' <<
                            setw(9) << row["sdate"] <<
                            endl;
                }

    条件结果行处理

    有时候,你需要从服务器拉一些并不需要的数据,然后在内存中过滤.使用Query::store_if().

    // Define a functor for testing primality.
    struct is_prime
    {
        bool operator()(const stock& s)
        {
            if ((s.num == 2) || (s.num == 3)) {
                return true;    // 2 and 3 are trivial cases
            }
            else if ((s.num < 2) || ((s.num % 2) == 0)) {
                return false;   // can't be prime if < 2 or even
            }
            else {
                // The only possibility left is that it's divisible by an
                // odd number that's less than or equal to its square root.
                for (int i = 3; i <= sqrt(double(s.num)); i += 2) {
                    if ((s.num % i) == 0) {
                        return false;
                    }
                }
                return true;
            }
        }
    };
    
    ......
    
    
    // Collect the stock items with prime quantities
    std::vector<stock> results;
    mysqlpp::Query query = con.query();
    query.store_if(results, stock(), is_prime());

    为结果集中每一行执行代码

    SQL不只是一个数据库查询语言.现代的数据库引擎可以在服务器端做一些数据的运算,但是这并不是最好的选择.如果你需要混合代码和查询,MySQL++提供了 Query::for_each()机制.

    // Define a functor to collect statistics about the stock table
    class gather_stock_stats
    {
    public:
        gather_stock_stats() :
        items_(0),
        weight_(0),
        cost_(0)
        {
        }
    
        void operator()(const stock& s)
        {
            items_  += s.num;
            weight_ += (s.num * s.weight);
            cost_   += (s.num * s.price.data);
        }
        
    private:
        mysqlpp::sql_bigint items_;
        mysqlpp::sql_double weight_, cost_;
    
        friend std::ostream& operator<<(std::ostream& os,
                const gather_stock_stats& ss);
    };
    
    
    // Dump the contents of gather_stock_stats to a stream in human-readable
    // form.
    std::ostream&
    operator<<(std::ostream& os, const gather_stock_stats& ss)
    {
        os << ss.items_ << " items " <<
                "weighing " << ss.weight_ << " stone and " <<
                "costing " << ss.cost_ << " cowrie shells";
        return os;
    }
    
     // Gather and display the stats for the entire stock table
    mysqlpp::Query query = con.query();
    std::cout << "There are " << query.for_each(stock(),
    gather_stock_stats()) << '.' << std::endl;

    连接选项

    MySQL有大量的选项来控制你连接数据库的方式,以及连接的行为.

    打开多重查询选项,并且建立连接

    Connection con;
    con.set_option(new MultiStatementsOption(true));
    
    // Connect to the database
    if (!con.connect(mysqlpp::examples::db_name, cmdline.server(),
      cmdline.user(), cmdline.pass())) {
      return 1;
    }

    执行多重查询

    // Set up query with multiple queries.
    Query query = con.query();
    query << "DROP TABLE IF EXISTS test_table; " <<
        "CREATE TABLE test_table(id INT); " <<
        "INSERT INTO test_table VALUE S(10); " <<
        "UPDATE test_table SET id=20 WHERE  id=10; " <<
         "SELECT * FROM test_table; " <<
         "DROP TABLE test_table";
     cout << "Multi-query: " << endl << query << endl;

    连接超时处理

    MySQL连接在长时间闲置后会被MySQL关闭,默认是8小时.

    一种处理连接超时的方式,是配置MySQL,重新设置其连接超时时间.

    第二种方式可以采用ReconnectOption,在MySQL连接断开后会进行自动重连

    第三种方式是使用Connection::ping()轮询检测连接是否关闭,如果关闭,就重新连接

  • 相关阅读:
    .Net Core ----通过XUnit进行接口单元测试(带请求头及参数)并用output输出结果
    .Net Core---- 通过EPPlus批量导出
    .Net Core---- 自带Json返回日期带T格式 解决
    You need tcl 8.5 or newer in order to run the Redis test
    exec: "docker-proxy": executable file not found in $PATH
    docker 如何清理垃圾呢
    docker run 报错——WARNING: IPv4 forwarding is disabled. Networking will not work.
    go 依赖包管理工具gb安装报错
    keepalived实现nginx高可用
    php命令行查看扩展信息
  • 原文地址:https://www.cnblogs.com/comoon/p/4118228.html
Copyright © 2011-2022 走看看