在本节中,我将首先介绍MYSQL++中的查询的几个简单例子用法,然后看一下mysqlpp::Query中的几个与查询相关的方法原型(重点关注返回值),最后对几个关键类型进行解释。

1. MYSQL++的查询实例

下面的两个例子分别是STORE(所有数据一次性从服务器拉到本地缓存)和USE(将数据一条一条从服务器拉到本地)的使用方式,其中STORE内部实质就是mysql_store(

),而USE实质就是调用了mysql_use( )。

说明,下面的例子虽然使用的都是最为基本的查询过程(即没有使用template

sql或者SSQLS),但是这个并不影响我们的讨论,因为遍历结果集的过程是一致的。

STOREmysqlpp::Query query = conn.query("select item from stock");

mysqlpp::StoreQueryResult res = query.store();

mysqlpp::StoreQueryResult::const_iterator it;

for (it = res.begin(); it != res.end(); ++it)

{

mysqlpp::Row row = *it;

// 第一列 row[0]

// 第二列 row[1]

}

USEmysqlpp::Query query = conn.query("select * from stock");

mysqlpp::UseQueryResult res = query.use();

while (mysqlpp::Row row = res.fetch_row())

{

row["item"];

row["num"];

}

// Check for error:

// can‘t distinguish "end of results" and

// error cases in return from fetch_row() otherwise

if (conn.errnum())

{

cout << "Error in fetch_row";

}

从上面的两个例子中我们大致可以看出来,整个结果集的查询过程就是针对相匹配的Result类型,找到ROW,然后逐行或者跳跃着查找。

2.

Result相关类型的使用场合

首先让我们回顾mysqlpp::Query中提到的几个方法,以及他们的返回值。以下部分内容直接摘自关于mysqlpp::Query的介绍的内容。

为了讲述方便,我们先来看一下在result.h(Declares classes for holding information about SQL

query)中所定义的各种类型的关系。这几个类型后面会仔细说明。

1)bool mysqlpp::Query::exec(const std::string& str);

这里返回的是bool,表示的是“语句是否执行成功”,我认为适合于那种update,

delete,insert,且都不关心有多少rows被touch的情况。

2)SimpleResult mysqlpp::Query::execute();

这里的SimpleResult正如其名,其中只有如下信息

the last value used for an AUTO_INCREMENT field

(ulonglong insert_id() const)

the number of rows affected by the query(ulonglong rows( ) const)

any additional information about the query returned by the server(const

char* info( ) const)

3)UseQueryResult mysqlpp::Query::use();

由于use的语义类似于使用游标,也就是支持一行一行地拉出内容,所以UseQueryResult 也就自然而然地支持一些关于fetch

row的功能。

4)StoreQueryResult mysqlpp::Query::store();

StoreQueryResult它本身就是从vector继承而来,所以它就是vector。所以用户程序可以直接使用下标的形式来获取所有的ROW。这也就是说在这个store之后,所有的ROW的内容都在了这个vecor里面了。

3.

Result相关类型解析

与Result相关的类型主要集中在result.h和result.cpp。

1) SimpleResult

这个类型非常简单,是一个比较单纯的类型,并没有父类。主要的成员变量有3个,分别是

// last value used for an AUTO_INCREMENT field

ulonglong insert_id_;

// the number of rows affected by the query

ulonglong rows_;

// any additional information about the query returned by the server

std::string info_;

成员方法也比较单纯,就是对上述几个字段的GET,构造函数就是对上述几个字段的SET。

以SimpleResult mysqlpp::Query::execute();为例,让我们来看一下MYSQL++是如何设置这个SimpleResult。

再来看一下Query::insert_id( ), Query::affected_rows( ), Query::info(

),这几个方法都直接delegate DBDriver的相关函数,直接返回了结果而已。

2) ResultBase

这个类型是StoreQueryResult和UseQueryResult的父类型,该类型其实没有特别的含义,只是作为一个common

methods的container而已。但是该类型提供的几乎所有的public methods都是和fields有关的,包括了

根据index查找field;

根据name查找field;

根据index查找到field的名字和属性类型;

获取当前所在的field(ResultBase内部会有一个mutable的index名为current_field_用于指明当前fetch_field的是哪一个field,在fetch_field中该index会自增)

该类型的核心成员有如下几个

Fields(std::vector) 类型的 fields_

FieldNames (继承自std::vector<: string>)类型的 names_

FieldTypes ( 继承自std::vector)类型的types_

其中FieldNames和FieldTypes都是被RefCountedPointer包裹着,估计这样做能够节省空间。关于Field类型在后续进行介绍。至于刚才说的几个找field的操作,看着这几个核心成员的类型还是比较好理解的。不就是在vector中不找。

需要额外关注的是以下这个最主要的构造函数

以下几点需要注意,

names_和types_在new出来之后是不需要显式delete的,因为他们都在智能指针RefCountedPointer包裹着。

成员初始化列表中的 fields_(Fields:: size_type(…)) 这一句其实调用的是

explicit std::vector::vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());

从以上构造函数可以看到,其实关于Field的信息还是从DBDriver中拿到的,然后关于FieldNames和FieldTypes的信息,则是通过这两个类型自身的构造函数给实现的(其实就是收到ResultBase*,然后遍历其中的成员变量

fields_ 再各求所需罢了。

为什么要有重新将指示field_当前index的指针重置的过程(dbd->field_seek(res,

0))?这是因为方便这个DBDriver再次循环访问这些fields。

3) StoreQueryResult

该类型是同时集成了ResultBase和vecor类型(请注意了,这个Result居然是一个vecor!)文档中说,该类型hold

results from a SQL query that returns rows: a specialization of std::vector

holding Row objects in memory so you get random-access semantics.

说白了,该类型在继承了ResultBase之后,只有以下这个构造函数是比较要紧的了。

有以下几点需要说明

StoreQueryResult继承自std::vector

在成员初始化列表中,首先调用ResultBase的构造函数

list_type是std::vector的typedef,所以在list_type(…)这一行,直接根据DBDriver返回的结果的rows的数量就布置好了vector的长度。

MYSQL_ROW是MYSQL自带的结构类型(定义域mysql.h中,typedef char **MYSQL_ROW;)

dbd->fetch_row(MYSQL_RES*)应该只是包装了mysql_fetch_row(MYSQL_RES*)这个MySql C

API,而dbd->fetch_lengths(MYSQL_RES*)其实包装的是mysql_fetch_lengths(MYSQL_RES*)这个MYSQL

C API,他获取的是整个row的对应的所有field的长度。

这一次Query的结果在全部拷贝完之后就释放了(dbd->free_result(res);)

如此一来,所有我们需要的信息都通过构造一个mysqlpp::Row对象来实现了。关于mysqlpp::Row的具体说明请看下文。

4) UseQueryResult

该类型拓展于ResultBase类型。根据MYSQL++ user

document的说法,UseQueryResule适用于For these large result sets,a “use” query tells the

database server to send the results back one row at a time, to be processed

linearly.

该类型的方法比StoreQueryResult丰富多了,主要体现在:

可以顺序读取行(mysqlpp::Row fetch_row() const;或者MYSQL_ROW fetch_raw_row()

const;)

可以获取当前行的各个field的信息(const Field& fetch_field() const; const Field&

fetch_field(Fields::size_type i) const)

可以获取当前行的所有fields的长度(const unsigned long* fetch_lengths() const;)

值得注意的是,UseQueryResult有一个成员变量mutable RefCountedPointer result_;

需要强调的有两点

MYSQL_RES是 MYSQL C API

中的用于做为资源的结构体,获取一行的函数mysql_fetch_one_row的参数就是MYSQL_RES*

RefCountedPointer是一个智能指针,但是就在定义这些result类型的result.h中,作者将其针对MYSQL_RES进行了具化,即

很显然,这个是为了在ref

count为0时自动调用析构器而准备的,该Destroyer使用mysql_free_result来销毁这里的result_,从而代替默认的delete操作。

接下来,我们来具体看几个函数的实现。

构造函数

获取fields的信息

请注意,这个result_是一个RefCountedPointer,所以调用的raw方法将会返回MYSQL_RES*

获取一行数据

核心的做法就是利用MYSQL_ROW  DBDriver::fetch_row(MYSQL_RES* res)

const。其实质也就是调用了mysql_fetch_one_row( )这个C API。然后直接生成一个mysqlpp::Row对象,返回。

原文:http://www.cnblogs.com/aicro/p/3633506.html

mysql 获取结果_【原创】7. MYSQL++中的查询结果获取(各种Result类型)相关推荐

  1. mysql硬盘备份_原创-在mysql中把里面的数据库备份到自己的硬盘上

    原创-在mysql中把里面的数据库备份到自己的硬盘上 (2011-04-15 20:33:23) 标签: 千百度女鞋 杂谈 在mysql中把内中的数值库备份到本人的硬盘上在数值库表拾失或许破坏的情况下 ...

  2. java 获取光标_如何在java中使用Windows API获取当前鼠标光标类型?

    这在Win7上对我很有用.该脚本使用Python,但应该很容易翻译成任何其他语言.当然,它仅在相应的应用程序不使用自定义游标时才有效: from win32con import IDC_APPSTAR ...

  3. mysql fnv算法_《高性能MySQL》读书笔记之创建高性能的索引

    索引是存储引擎用于快速找到记录的一种数据结构.索引优化是对查询性能优化的最有效手段.索引能够轻易将查询性能提高几个数量级.创建一个最优的索引经常需要重写查询. 5.1索引基础 在MySQL中,存储引擎 ...

  4. mounted钩子函数_怎样实现Vue中mounted钩子函数获取节点高度

    这次给大家带来怎样实现Vue中mounted钩子函数获取节点高度,实现Vue中mounted钩子函数获取节点高度的注意事项有哪些,下面就是实战案例,一起来看一下. 遇到的问题 最近在开发一个Vue的项 ...

  5. mysql 自然排序_如何在mysql中实现自然排序

    背景 熟悉mysql的同学应该清楚,mysql在对字符串做order by排序时是按照字典序进行排序的,但是如果字符串中包含数字的话(我们称这种类型的字符串为alphanumeric),仅按照字典序的 ...

  6. mysql 获取当前日期_详解mysql 获取当前日期及格式化

    本篇文章主要介绍了mysql 获取当前日期及格式化,具有一定的参考价值,感兴趣的小伙伴们可以参考一下. MySQL 获取当前日期及日期格式 获取系统日期: NOW() 格式化日期: DATE_FORM ...

  7. 树莓派查看mysql的密码_树莓派安装MySQL 后若何获取登录密码

    树莓派安装MySQL后获取登录密码 树莓派基于Debian系统. 乐成安装MySQL后 su root vim /etc/mysql/debian.cnf 其中 user 和 password 就是你 ...

  8. docker容器mysql头文件_在Docker容器中使用MySQL数据库

    开发过程中经常需要安装.调试mysql数据库,还需要在各种操作系上安装包依赖,实在是繁琐,因此就研究了一下如何在docker上运行一个mysql镜像,省却了我安装.找依赖的问题. 注:本文所有内容均在 ...

  9. mysql列连接_连接来自MySQL中不同表的列

    您可以使用CONCAT().让我们首先创建一个表-mysql> create table DemoTable1 -> ( -> FirstName varchar(20) -> ...

最新文章

  1. 欧洲顶级云数据中心着火,损失惨重!筑牢数据中心“防火墙”,可靠才是王道!...
  2. Query 快速入门教程
  3. 使用C#实现适配器模式 (Adapter Pattern) 和外观模式 (Facade Pattern)
  4. 区块链学习笔记:DAY05 如何使用公有云区块链服务
  5. 联想Z6预告海报公布:最轻4000mAh手机,没有之一
  6. C++Primer学习第四章
  7. 删除IE 下输入后的清除小叉叉
  8. JCam2 v1.6.0 USB摄像头工具全新发布及使用详解
  9. 词法分析器(分析C语言)
  10. mysql中添加外键语句_数据库语句怎么加外键
  11. 十个随机数排列(vb代码)
  12. Vue周日历展示大学课程
  13. mysql年龄最大_使用MySQL子查询选择年龄最大的所有用户?
  14. IDP(个人发展计划)
  15. Pale Transformer: A General Vision Transformer Backbone with Pale-Shaped Attention
  16. 2021全国职业技能大赛-网络安全赛题解析总结②(超详细)
  17. java8:新特性及Lamber表达式语法及四大函数接口
  18. “为了交项目干杯”对“那周余嘉熊掌将得队”、“男上加男,强人所男”的Beta产品测试报告...
  19. Blender 基础操作
  20. 彻底解决python关于各种文件(音乐、视屏等)读写的操作

热门文章

  1. win10 解决升级 WordPress 时提示”另一更新正在进行”
  2. 【RK3399Pro学习笔记】十、ROS服务端Server的编程实现
  3. Linux 设备驱动的并发控制
  4. PyRun_SimpleString的无穷怨念
  5. 如何处理Oracle客户端查询乱码问题
  6. [react] shouldComponentUpdate方法是做什么的
  7. 前端学习(3345):数组方法的使用
  8. React开发(137):ant design学习指南之form中日期时间处理format时间处理
  9. Taro+react开发(7)--控制跳转
  10. 小程序学习(1):微信开发者工具安装