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()轮询检测连接是否关闭,如果关闭,就重新连接

时间: 2024-08-05 17:24:29

Mysql++学习(三)------举个栗子的相关文章

MySql 学习三(多对多)

在我的前一篇博客中学习了一点点数据库的基础知识,今天我们一起学习数据库中的多对多的数据库的设计.在我们的日常生活中有哪些是多对多的数据关系呢?如果你还是一个学生,可能最容易想到的就是老师和学生的关系.一个老师肯定给多个学生上过课,同时一个学生也听过很多老师的课.如果你是一名销售,可能最容易想到的就是订单和客户的关系.总之,生活中多对多的关系实在是太多了. 实例: 下面我们就以老师和学生的关系来理解数据库中的多对多的关系: 假设:老师的信息有id,name,salary,学生的信息有 id,nam

MySql学习(三) —— 子查询(where、from、exists) 及 连接查询(left join、right join、inner join、union join)

同样的,使用goods表来练习子查询,表结构如下: 所有数据(cat_id与category.cat_id关联): 类别表: mingoods(连接查询时作测试) 一.子查询 1.where型子查询:把内层查询的结果作为外层查询的比较条件 1.1 查询id最大的一件商品(使用排序+分页实现) :mysql> SELECT goods_id,goods_name,shop_price FROM goods ORDER BY goods_id DESC LIMIT 1; 1.2 查询id最大的一件商

MySQL学习(三)——Java连接MySQL数据库

1.什么是JDBC? JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句. 2.JDBC原理 SUN提供访问数据库规范称为JDBC,而生产厂商提供的实现类称为驱动. JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接! 每个数据库厂商都有自己的驱动,用来连接自己公司的数据库. 3.JDBC开发步骤

MySQL 学习三 关于转义

DB2 LIKE谓词查询语句中支持 百分号(%).下划线(_)的使用,不支持方括号([])(注:它会把方括号当成实际的值而非通配符),当我们需要在LIKE 查询条件中将百分号(%).下划线(_)作为实际值进行查询时,就需要使用转义字符告诉DB2把它们当做是实际值而非转义字符.然而,DB2中并非定义了转义字符(反斜杠\在DB2中并非转义字符),所以需要使用ESCAPE关键字来定义,LIKE '%!%' ESCAPE '!'. 值得注意的是,对于单引号的处理与百分号(%).下划线(_)的处理有点不一

Mysql学习笔记(三)对表数据的增删改查。

写在前面:(一些牢骚,可以直接跳到分割线后) 太过敏感的人不会快乐,不幸的是我正是这种性格的人. 从培训机构毕业后,迫于经济方面的压力,和当时的班里的一个同学住在了一起,我们在一个公司上班.谁知道这都是不开心生活的源头,从每天早晨开始心情就很糟糕.他是个脾气很慢的人,我是个急脾气,特别是在早上上班的时候.由此种种吧,实在是不胜枚举.算了,还是不说了,太痛苦了,我不太喜欢说别人的坏话.我是学心理学的,已经用各种方法去安慰自己,但是都不太奏效. 回想以往和朋友的交往中,我虽然不算十分合群的人,但绝对

我的MYSQL学习心得(三)

我的MYSQL学习心得(三) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(四) 查看字段的长度 SQLSERVER USE [sss] GO SELECT LEN([NAME]) FROM [dbo].[aa] MYSQL CREATE TABLE tmp13(vb VARBINARY(10)) INSERT INTO tmp13 (vb) VALUES(12) SELECT LENGTH(vb) FROM tmp13 INSERT INTO tmp13

Mysql学习笔记(三)运算符和控制流函数

原文:Mysql学习笔记(三)运算符和控制流函数 本章学习内容: 1.操作符 2.控制流程函数 操作符: i.圆括号.. 简单的介绍一下圆括号,圆括号的使用的目的是规定计算表达式的顺序...这个想必大家都熟悉例如  mysql>select 1+(2*3) mysql>select (1+2)*3 ii.比较运算符. 比较运算符就比较多了,并且也很常用..比如 = 等于: mysql> SELECT 1 = 0; -> 0 mysql> SELECT '0' = 0; -&g

基于CentOS的MySQL学习补充三--使用Shell批量创建数据库表

本文出处:http://blog.csdn.net/u012377333/article/details/47006087 接上篇介绍<基于CentOS的Mysql学习补充二--使用Shell创建数据库>,本文继续探索关于Shell和MySQL的结合使用,我不知道当一个数据库设计完成之后如何快速的创建设计好的数据库表和添加相应基本数据,我目前知道的就是使用Shell和SQL脚本来达到我的目的--快速的.多次的.可重复利用的创建数据库表. 创建一个数据库表的SQL脚本: /***********

MySQL学习笔记_13_Linux下C++/C连接MySQL数据库(三) --处理返回数据

 Linux下C++/C连接MySQL数据库(三) --处理返回数据 一.通过返回结果集中的字段数 [cpp] view plaincopyprint? unsigned int mysql_field_count(MYSQL * connection); //将MYSQL_ROW的值作为一个存储了一行数据的数组... unsigned int mysql_field_count(MYSQL * connection); //将MYSQL_ROW的值作为一个存储了一行数据的数组... 示例: