mysql++安装、使用详解、编程Demo



官网:https://tangentsoft.com/mysqlpp/home
官方手册:https://tangentsoft.com/mysqlpp/doc/html/refman/

参考博客:
https://www.cnblogs.com/aicro/category/565280.html
https://www.cnblogs.com/comoon/p/4104482.html



mysql++



1. Introduction(简介)

MySQL++是官方发布的一套C++ API;
MySQL++是对MySQL和MariaDB C api的再次封装,是 MySQL C API 的强大 C ++包装器(使用 STL 容器);

它建立在与标准c++库相同的原则之上,使处理数据库如同处理std容器(STL)一样简单。
MySQL++还提供了一些工具,可以让您在自己的代码中避免重复的SQL,为这些常见任务提供了本地c++接口。


1.1 CentOS7安装mysql++ - 3.2.5

#首先确保安装了mysql,如果已经安装了跳过此步骤
yum install mysql-devel

#下载MySQL++源码并解压
wget http://www.tangentsoft.net/mysql++/releases/mysql++-3.2.5.tar
tar -zxvf mysql++-3.2.5.tar
mv mysql++-3.2.5 mysql++
cd mysql++

#执行./configure生成makefile文件
./configure --enable-thread-check --enable-disasm LDFLAGS='-pthread'

#编译出libmysqlpp.so
make
make install

#install成功后会将.so文件拷贝到/usr/local/lib下,并把.h头文件拷贝到/usr/local/include下。

# g++编译器只会使用/lib和/usr/lib这两个目录下的库文件
# 所以添加库路径并使之生效
vim /etc/ld.so.conf
	添加libmysqlpp.so的路径(/usr/local/lib),保存并退出
ldconfig


#创建so的连接:
ln -s /usr/local/lib/libmysqlpp.so /usr/lib/libmysqlpp.so


2. Overview(概述)

写代码的步骤:

  1. 打开连接
  2. 形成并执行查询
  3. 如果成功,则遍历结果集
  4. 否则,处理错误

每个步骤都对应一个 MySQL ++类或类层次结构。



2.1 The Connection Object(连接对象)


https://tangentsoft.com/mysqlpp/doc/html/refman/classmysqlpp_1_1Connection.html


Connection 对象管理与 MySQL 服务器的连接。

MySQL 支持客户端和服务器之间的许多不同类型的数据连接:

  1. TCP/IP、
  2. Unix domain sockets(Unix 域套接字)、
  3. Windows named pipes(Windows 命名管道)

通用 Connection 类支持所有这些(基于您传递给 Connection :: connect()的参数从而找出哪一个)。但是如果您事先知道程序只需要一种特定的连接类型,有具有更简单接口的子类。例如:如果知道程序将始终使用联网的数据库服务器,则使用 TCPConnection。


所有的链接操作可以通过使用mysqlpp::Connection类型进行;
为了方便起见,mysqlpp还提供了TCPConnection,UnixDomainSocketConnection以及WindowsNamedPipeConnection。
但是一般情况只需要通过Connection的不同Connect方法overload就可以进行连接。



2.2 The Query Object(查询对象)

通常使用由 Connection 对象创建的 Query 对象创建 SQL 查询。

查询语句的形式:

1 Query acts as a standard C++ output stream(Query充当标准的c++输出流),因此可以像向std::cout或std::ostringstream那样向它写入数据。mysql++库包括可识别类型的流操纵器,因此很容易建立语法正确的SQL。

2 Query还具有称为模板查询的功能,它的工作方式类似于C的printf()函数:您设置了一个固定的查询字符串,其中带有标记,这些标记指示在何处插入变量部分。如果有多个结构相似的查询,只需设置一个模板查询,然后在程序的各个位置使用它。

3 建立查询的第三种方法是将查询与 SSQLS 一起使用。该特性允许您创建映射数据库模式的c++结构。这些又为 Query 提供了构建许多常见 SQL 查询所需的信息。给定 SSQLS 格式的数据,它可以在表中 INSERT,REPLACE 和 UPDATE 行。它也可以产生SELECT * FROM SomeTable 查询并将结果存储为 SSQLSes 的 STL 集合。


MYSQL++支持的查询方法是

  1. 直接使用Query stream输入SQL语句
  2. 使用Template Query采用类似于printf的方式进行输入SQL语句
  3. 使用SSQLS,通过类似于Hibernate的方式对Data Struct进行操作来操作底层数据库


2.3 Result Sets(结果集)


MYSQL++支持三种遍历数据结果的方法,

  1. 所有数据结果行都拿出来到内存(store)
  2. 游标一样逐行操作(use)
  3. 类似于Hibernate的利用DataStruct进行直接操作的方式

结果集中的字段数据存储在一个特殊的std:: String类中,称为String。该类具有转换操作符,可以自动将这些对象转换为任何基本的C数据类型。另外,MySQL++定义了DateTime类,可以从一个MySQL DATETIME字符串初始化。这些自动转换受到保护,不受坏转换的影响,可以设置警告标志或抛出异常,这取决于您如何设置库。

对于结果集,MySQL++有很多不同的方式来表示它们:

2.3.1 Queries That Do Not Return Data(不返回数据的查询)

并不是所有的SQL查询都返回数据。例如:CREATE TABLE。对于这些类型的查询,有一种特殊的结果类型(SimpleResult),它只报告查询产生的状态:查询是否成功,它影响了多少行(如果有的话),等等。

2.3.2 Queries That Return Data: MySQL++ Data Structures(返回数据的查询:MySQL ++数据结构)

检索结果集最直接的方法是使用Query::store()。
这将返回一个StoreQueryResult对象,该对象派生自std::vectormysqlpp::Row,使其成为一个随机访问的行容器。
反过来,每个Row对象就像String对象的std::vector,一个对象对应结果集中的每个字段。
因此,可以将StoreQueryResult作为一个二维数组:
可以通过result[1][4]来获得第2行上的第5个字段。
还可以通过字段名访问行元素,像这样:result[2][“price”]。

处理查询结果的一种不那么直接的方法是使用query::use(),它返回一个UseQueryResult对象。
这个类的作用类似于STL输入迭代器,而不是std::vector:每次处理一行 遍历结果集,始终向前。
你无法在结果集中到处查找,而且你不知道集合中有多少结果 直到你找到结果的末尾。
但是,您可以获得更好的内存效率,因为整个结果集不需要存储在RAM中。当您需要大型结果集时,这非常有用。

2.3.3 Queries That Return Data: Specialized SQL Structures(返回数据的查询:特殊的 SQL 结构)

通过 MySQL ++的数据结构访问结果是一个相当低的抽象层次。它比使用MySQL C API好,但也差不了多少。
通过使用SSQLS 特性,您可以将问题提升到更接近问题空间的层次。
这允许您定义与数据库中的表结构相匹配的c++结构。此外,可以很容易地将SSQLSes与常规STL容器(以及算法)一起使用,因此不必处理MySQL++奇怪的数据结构。

这种方法的优点是您的程序只需要嵌入很少的SQL代码。您可以简单地执行一个查询,并以c++数据结构的形式接收结果,可以像访问任何其他结构一样访问这些数据结构。可以通过Row对象访问结果,也可以要求库将结果转储到STL容器中——顺序的或关联的,这对您来说没什么关系。考虑一下:

vector<stock> v;
query << "SELECT * FROM stock";
query.storein(v);
for (vector<stock>::iterator it = v.begin(); it != v.end(); ++it) 
{
 	cout << "Price: " << it->price << endl;
}

用起来是不是很顺畅?
如果您不想创建SSQLSes来匹配您的表结构,从MySQL++ v3开始,现在可以在这里使用Row
而不是:

vector<mysqlpp::Row> v;
query << "SELECT * FROM stock";
query.storein(v);
for (vector<mysqlpp::Row>::iterator it = v.begin(); it != v.end(); ++it) 
{
 	cout << "Price: " << it->at("price") << endl;
}

它缺乏某种语法上的优雅,但它有自己的用途

2.4 Exceptions(例外)

默认情况下,库在遇到错误时抛出异常。
如果愿意,您可以要求库设置一个错误标志,但异常包含更多信息。
它们不仅包含一个字符串成员,告诉您为什么抛出异常,而且还有几种异常类型,因此您可以在单个try块中区分不同的错误类型。



3. 使用(相关类的介绍)

mysqlpp::OptionalExceptions
就是一个对于一个表示“是否需要抛出异常”的变量的包装。在Connection类型的内容,会在出现错误的时候调用OpetionalExceptions.throw_exceptions( )方法来查看是否需要使用异常的手段来表示错误。

mysqlpp::Connection
这个类型是用户程序能够看到的少数几个类型,它所包含的主要的方法就是
“连接”,
“断开连接”,
“创建某个数据库" “CREATE DATABASE”,
”drop某个数据库“ DROP DATABASE实现的,
”查看某张 table 中的数据行数“,
”关闭mysql服务
等操作“。

同时,该类型也可以返回一个mysqlpp::Query类型,该类型主要负责查询操作。另外,当我们以后看到mysqlpp::Query的时候,我们很容易发现它的构造函数必定需要一个mysqlpp::Connection,也就是说mysqlpp::Query的所有操作,其实也就是再次调用mysqlpp::Connection的对应方法,后者再去调用mysqlpp::DBDriver来做真正的数据库操作。

需要注意的是,Connection其实就是一个代理类型,所有的和数据库进行操作的非查询类动作(包括了连接,查看连接是否还在,MYSQL的操作出错的错误信息和错误号,通信方式(ipc_info方法),选择当前DB)都是交给mysqlpp::DBDriver来做的。他才是真正的执行者。

mysqlpp:: Query 进行SQL语句的增删改查
mysqlpp::StoreQueryResult 所有数据结果行
mysqlpp::UseQueryResult 游标一样逐行操作
mysqlpp::ConnectionPool 连接池

3.1 mysqlpp::Connection

官方手册:

https://tangentsoft.com/mysqlpp/doc/html/refman/

https://tangentsoft.com/mysqlpp/doc/html/refman/classmysqlpp_1_1Connection.html

#include <connection.h>

在这里插入图片描述

在这里插入图片描述

3.2 mysqlpp::Query

3.3 mysqlpp::Row

3.4 mysqlpp::StoreQueryResult

3.5 mysqlpp::UseQueryResult

4. user manual.上的例子及Makefile

  • helloMySQL++.cpp
#include <mysql++/mysql++.h>

int main()
{
	mysqlpp::String greeting("Hello, world!");
	std::cout << greeting << std::endl;
	return 0;
}
  • Makefile
# 头文件目录
CXXFLAGS := -I/usr/include/mysql 			\
			-I/usr/local/include/mysql++ 

# 库目录		
LDFLAGS := -L/usr/local/lib					\
		   -L/usr/lib64/mysql/
# 动态库
LDLIBS := -lmysqlpp 						\
		  -lmysqlclient

# 源文件
EXECUTABLE := helloMySQL++

all: $(EXECUTABLE)

clean:
	rm -f $(EXECUTABLE) *.o
[root@lwh testcpp]# ./helloMySQL++ 
Hello, world!
[root@lwh testcpp]# 

5. /mysql+±3.2.5/examples/目录的(官方)例子

5.0 运行官方demo之前,首先得有个数据库,执行安装目录下的resetdb

./resetdb -s 127.0.0.1 -u [user]-p [password]
[root@lwh mysql++-3.2.5]# ./resetdb -s 127.0.0.1 -u root -p root123
Connecting to 'root'@'127.0.0.1', with password...
Dropping existing sample data tables...
Creating stock table...
Populating stock table...inserted 4 rows.
Creating empty images table...
Creating deadlock testing tables...
Reinitialized sample database successfully.
[root@lwh mysql++-3.2.5]# 

可以看到mysql中多了一个数据库mysql_cpp_data

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| MySQLCrashCourse   |
| information_schema |
| mysql              |
| mysql_cpp_data     | !!!!!
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.01 sec)

mysql> 

5.1 simple1.cpp

#include <iostream>
#include <errno.h>
#include <mysql++/mysql++.h>
using namespace std;

/*
mysql -uroot -proot123
use MySQLCrashCourse
select * from customers;
*/
int main(int argc, char *argv[])
{
	mysqlpp::Connection conn(false);
	if (conn.connect("mysql_cpp_data", "127.0.0.1", "root", "root123"))
	{
		// Retrieve a subset of the sample stock table set up by resetdb
		// and display it.
		mysqlpp::Query query1 = conn.query("select item from stock");
		if (mysqlpp::StoreQueryResult res = query1.store())
		{
			cout << "We have:" << endl;
			mysqlpp::StoreQueryResult::const_iterator it;
			for (it = res.begin(); it != res.end(); ++it)
			{
				mysqlpp::Row row = *it;
				cout << '\t' << row[0] << endl;
			}
		}
		else
		{
			cerr << "Failed to get item list: " << query1.error() << endl;
			return 1;
		}

		mysqlpp::Query query2 = conn.query("select * from stock");
		if (mysqlpp::StoreQueryResult res = query2.store())
		{
			cout.setf(ios::left);
			cout << setw(31) << "item"
				 << setw(10) << "num"
				 << setw(10) << "weight"
				 << setw(10) << "price"
				 << "sdate" << endl;

			for (size_t i = 0; i < res.num_rows(); i++)
			{
				cout << setw(30) << res[i]["item"]
					 << setw(9) << res[i]["num"]
					 << setw(9) << res[i]["weight"]
					 << setw(9) << res[i]["price"]
					 << setw(9) << res[i]["sdate"] << endl;
			}
		}
		else
		{
			cerr << "Failed to get item list: " << query2.error() << endl;
			return 1;
		}
		return 0;
	}
	else
	{
		cerr << "DB connection failed: " << conn.error() << endl;
		return 1;
	}
}
# ./simple1++  -s 127.0.0.1 -u root -p root123 改写后不需要传参

[root@lwh mysql++test]# make
g++ -I/usr/include/mysql -I/usr/local/include/mysql++   -L/usr/local/lib -L/usr/lib64/mysql/  simple1.cpp  -lmysqlpp -lmysqlclient -o helloMySQL++
[root@lwh mysql++test]# ./simple1  
We have:
        Nürnberger Brats
        Pickle Relish
        Hot Mustard
        Hotdog Buns
item                           num       weight    price     sdate
Nürnberger Brats             97       1.5      8.79     2005-03-10
Pickle Relish                 87       1.5      1.75     1998-09-04
Hot Mustard                   73       0.95     0.97     1998-05-25
Hotdog Buns                   65       1.1      1.10     1998-04-23
[root@lwh mysql++test]# 
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值