Linux环境下Mysql++安装及操作深入详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 题记:之前项目中使用OTL连接操作Oracle数据库,对于Mysql有用,但没有总结。目前常用的两种连接方式:

方式一:mysql conncetor

(http://dev.mysql.com/downloads/connector/c/), mysql官网提供。


方式二:mysql++。

由于mysql connector我没有用过,不做评价。把mysql ++ 的优点列一下,对比mysql connector:

1)mysql++历史更悠久;

2)mysql++是第三方库;

3)mysql++编程风格:使用 使用原生的C++标准库和STL。而mysql conncetor更像JAVA风格。

4)mysql++更成熟。

原作者给出的比较:

http://www.zeuux.com/group/candcplus/bbs/content/55922/


本文主要详解:

Linux(确切是Centos)下msyql++的安装、增、删、改、查源码封装接口实现。


1、Mysql++作用

Mysql++是官方发布的、为MySQL设计的C++语言的API,这个API的作用是使工作更加简单且容易。

Mysql++为Mysql的C-Api的再次封装,它用STL开发并编写,并为C++开发程序员提供象操作STL容器一样方便的操作数据库的一套机制。

经常使用STL、OTL的朋友,使用起来会非常方便。


下载地址:https://tangentsoft.net/mysql++/


2、Mysql++安装步骤(CentOS release 6.8 (Final))

第1步:安装 libmysqlclient


yum install mysql-devel

1

2

libmysqlclient.so安装位置查看:



[root@laoyang testMysqlConn]# rpm -ql mysql-devel

********

/usr/lib64/mysql/libmysqlclient.so

1

2

3

4

如上,从结果中可以看到libmysqlclient.so在/usr/lib64/mysql/目录下


第2步: 安装mysql3.2.2

1)解压:

mysql3.2.2 .tar.gz ,默认目录为:mysql++-3.2.2


2)配置

./configure –prefix=/usr/local –enable-thread-check –with-mysql-lib=/usr/lib64/mysql


3)编译

make


4)安装

make install


5)修改/etc/ld.so.conf文件,

添加如下内容:



/usr/local/lib

/sbin/ldconfig

/bin/ln -s /usr/local/lib/libmysqlpp.so /usr/lib/libmysqlpp.so

1

2

3

4

至此,mysql++安装配置ok。


3、Mysql++操作

3.1 核心功能点:

1)通过Mysql++类库,连接Mysql。

2)实现对Mysql的增、删、改、查操作。


3.2 用户手册

API的详细介绍及使用Demo

http://tangentsoft.net/mysql++/doc/html/userman/


3.3 核心接口

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


1)execute( )接口

用于不返回数据的查询,该函数返回一个SimpleResult对象。


2)exec( )接口

它返回一个bool值,标示执行成功与否;如果只要成功与否的标识,可以使用该接口。


3)store() 接口

用于用服务器获取数据,该函数返回一个StoreQueryResult对象。对象包含了整个查询结果,使用stl::map方式从里面取数据即可。


4)use()接口

同样用于从服务器获取数据,不过该函数返回UseQueryResult对象。相比store()而言更节省内存,该对象类似StoreQueryResult,但是不提供随机访问的特性。use查询会让服务器一次返回结果集的一行。

Query对象的errnum()返回上次执行对应的错误代码,error()返回错误信息,affected_rows()返回受影响的行数。


3.4 实战源码实现:

1)test.cpp内容如下:


#include <mysql++.h>

#include <stdlib.h>

#include <stdio.h>

#include <string>

#include <iostream>

using namespace std;

using namespace mysqlpp;


//insert into cc(id, name, status) values(22, "laoyang", "ok");

const char* g_szInsertFormat = "insert into cc(id, name, status) values(%d, \"%s\", \"%s\");";

const char* g_szUpdateFormat = "update cc set name = \"%s\" where id = %d;";

const char* g_szDeleteFormat = "delete from cc where id = %d;";

const char* g_szSearchFormat = "select * from cc;";


#define DATEBASE_NAME "test"

#define DATEBASE_IP "192.168.1.1"

#define DATEBASE_USERNAME "admin"

#define DATEBASE_PWD "**********"


#define DATA_BUF_SIZE 2048


//增

void insertFun(Query* pQuery)

{

 cout << "Inserting test" << endl;

 char szInsert[DATA_BUF_SIZE] = {0};

 memset(szInsert, 0, DATA_BUF_SIZE);

 int iId = 66;

 const char* pszName = "Miss Zhangx";

 const char* pszStatus = "OK";


 sprintf((char*)szInsert, g_szInsertFormat, iId, pszName, pszStatus);

 cout << "szInsert = " << szInsert << endl;


 *pQuery << szInsert;

 SimpleResult res = pQuery->execute();

 // Report successful insertion

 cout << "Inserted into cc table, ID =" << res.insert_id() << endl;

 cout << endl;

}


//删

void deleteFun(Query* pQuery)

{

 cout << "deleting test" << endl;

 char szDelete[DATA_BUF_SIZE] = {0};

 int iId = 44;

 memset(szDelete, 0, DATA_BUF_SIZE);

 sprintf((char*)szDelete, g_szDeleteFormat, iId);

 cout << "szDelete = " << szDelete << endl;


 *pQuery << szDelete;

 if (pQuery->exec())

 {

 cout << "deleted success!" << endl;

 }

 cout << endl;

}


//改

void updateFun(Query* pQuery)

{

 cout << "updating test" << endl;

 char szUpdate[DATA_BUF_SIZE] = {0};

 memset(szUpdate, 0, DATA_BUF_SIZE);


 int iId = 2;

 const char* pszNewName = "new line 2 revise";


 sprintf((char*)szUpdate, g_szUpdateFormat, pszNewName, iId);

 cout << "szUpdate = " << szUpdate << endl;


 *pQuery << szUpdate;

 if (pQuery->exec())

 {

 cout << "updated success!" << endl;

 }

 cout << endl;

}


//查

void searchFun(Query* pQuery)

{

 /* Now SELECT */

 cout << "selecting test:" << endl;

 *pQuery << g_szSearchFormat;

 StoreQueryResult ares = pQuery->store();

 cout << "ares.num_rows() = " << ares.num_rows() << endl;

 for (size_t i = 0; i < ares.num_rows(); i++)

 {

 cout << "id: " << ares[i]["id"] << "\t - Name: " << ares[i]["name"] \

 << "\t - Status: " << ares[i]["status"] << "\t - Modified_at" << ares[i]["modified_at"] << endl;

 }


 /* Let's get a count of something */

 *pQuery << "SELECT COUNT(*) AS row_count FROM cc";

 StoreQueryResult bres = pQuery->store();

 cout << "Total rows: " << bres[0]["row_count"] << endl;

 cout << endl;

}


int main()

{

 try

 {

 Connection conn(false);

 conn.connect(DATEBASE_NAME, DATEBASE_IP, DATEBASE_USERNAME, DATEBASE_PWD);

 Query query = conn.query();


 /*insert , delete , update, search testing */

 (void)insertFun(&query);

 (void)deleteFun(&query);

 (void)updateFun(&query);

 (void)searchFun(&query);


 }

 catch (BadQuery er)

 { // handle any connection or

 // query errors that may come up

 cerr << "Error: " << er.what() << endl;

 return -1;

 }

 catch (const BadConversion& er)

 {

 // Handle bad conversions

 cerr << "Conversion error: " << er.what() << endl <<

 "\tretrieved data size: " << er.retrieved <<

 ", actual size: " << er.actual_size << endl;

 return -1;

 }

 catch (const Exception& er)

 {

 // Catch-all for any other MySQL++ exceptions

 cerr << "Error: " << er.what() << endl;

 return -1;

 }


 return (EXIT_SUCCESS);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

2)makefile文件:


[root@laoyang testMysqlConn]# cat Makefile

CXX := g++

CXXFLAGS := -I/usr/include/mysql -I/usr/local/include/mysql++

LDFLAGS := -L/usr/lib64/mysql -lmysqlpp -lmysqlclient -lnsl -lz -lm

EXECUTABLE := main


all: test


clean:

 rm -f $(EXECUTABLE) *.o

1

2

3

4

5

6

7

8

9

10

11

3)执行结果如下:


[root@laoyang testMysqlConn]# ./test

Inserting test

szInsert = insert into cc(id, name, status) values(66, "Miss Zhangx", "OK");

Inserted into cc table, ID =66


deleting test

szDelete = delete from cc where id = 44;

deleted success!


updating test

szUpdate = update cc set name = "new line 2 revise" where id = 2;

updated success!


selecting test:

ares.num_rows() = 11

id: 1 - Name: laoyang360 - Status: ok - Modified_at0000-00-00 00:00:00

id: 2 - Name: new line 2 revise - Status: ok - Modified_at2016-06-23 06:16:42

id: 11 - Name: test11 - Status: ok - Modified_at2016-06-24 02:09:15

id: 5 - Name: jdbc_test_update08 - Status: ok - Modified_at0000-00-00 00:00:00

id: 7 - Name: test7 - Status: ok - Modified_at0000-00-00 00:00:00

id: 8 - Name: test008 - Status: ok - Modified_at0000-00-00 00:00:00

id: 9 - Name: test009 - Status: ok - Modified_at0000-00-00 00:00:00

id: 10 - Name: test10 - Status: ok - Modified_at2016-06-24 02:08:14

id: 22 - Name: laoyang - Status: ok - Modified_at2016-08-27 06:24:05

id: 55 - Name: Miss Zhang - Status: OK - Modified_at2016-08-27 07:40:38

id: 66 - Name: Miss Zhangx - Status: OK - Modified_at2016-08-27 08:41:51

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

4、易出错点

1) /usr/bin/ld: cannot find -lmysqlclient

修正方法:Makefile文件中包含mysqlclient.so的路径:/usr/lib64/mysql。


2)程序初始编译出“segment fault” 调试方法

第1步:让core显示出来

编辑/root/.bash_profile文件,在其中加入 ulimit -S -c unlimited , 如下:



[root@laoyang testMysqlConn]# tail -f /root/.bash_profile

ulimit -S -c unlimited

1

2

3

第2步:调试

gdb 可执行文件 core文件

gdb test core.10968


5、下一步工作

对mysql++如果可能的化,封装成自己常用的类。目前已经基本相对清晰。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
1月前
|
Ubuntu Linux
任何Ubuntu用户都应安装的四大Linux应用程序
当然,这款程序不需要太多介绍。我们面对的是网上最庞大最完整的多媒体中心,由于丰富的插件,我们能够高度细化地定制其每一项功能。这是我们的Linux发行版不可或缺的必备软件。 我们可以通过运行以下命令来轻松安装Kodi:sudo apt install kodi。
|
1月前
|
Ubuntu 物联网 Linux
从零安装一个Linux操作系统几种方法,以Ubuntu18.04为例
一切就绪后,我们就可以安装操作系统了。当系统通过优盘引导起来之后,我们就可以看到跟虚拟机中一样的安装向导了。之后,大家按照虚拟机中的顺序安装即可。 好了,今天主要介绍了Ubuntu Server版操作系统的安装过程,关于如何使用该操作系统,及操作系统更深层的原理,还请关注本号及相关圈子。
|
25天前
|
Ubuntu 关系型数据库 MySQL
Ubuntu 22.04.1上安装MySQL 8.0及设置root密码的注意事项
这些是在Ubuntu 22.04.1 系统上安装MySQL 8.0 及设置root密码过程中必须考虑的关键点。正确的遵循这些步骤可确保MySQL的安装过程既顺利又安全。
395 20
|
19天前
|
存储 关系型数据库 MySQL
在CentOS 8.x上安装Percona Xtrabackup工具备份MySQL数据步骤。
以上就是在CentOS8.x上通过Perconaxtabbackup工具对Mysql进行高效率、高可靠性、无锁定影响地实现在线快速全量及增加式数据库资料保存与恢复流程。通过以上流程可以有效地将Mysql相关资料按需求完成定期或不定期地保存与灾难恢复需求。
107 10
|
18天前
|
存储 Linux
Linux环境下删除大文件后磁盘空间未释放问题诊断流程。
以上诊断流程涉及Linux底层机制与高级管理技能结合之处,并需要管理员根据实际环境灵活调整诊断策略与解决方案。
75 8
|
18天前
|
弹性计算 安全 Linux
阿里云服务器ECS安装宝塔Linux面板、安装网站(新手图文教程)
本教程详解如何在阿里云服务器上安装宝塔Linux面板,涵盖ECS服务器手动安装步骤,包括系统准备、远程连接、安装命令执行、端口开放及LNMP环境部署,手把手引导用户快速搭建网站环境。
|
1月前
|
安全 Ubuntu Linux
如何安装Linux操作系统?
此时,您可以选择重新启动计算机,然后从硬盘上的Linux系统启动。以上是一个大致的安装过程。请注意,不同的Linux发行版可能会在细节上有所差异,因此在进行安装之前,请确保您阅读并理解了相应发行版的安装指南或文档。
|
1月前
|
Ubuntu Linux 数据安全/隐私保护
Win10安装Linux子系统教程!如何在Win10系统中安装Ubuntu!
登录系统后,输入cd /返回上一级,然后再输入“ls”查看一下系统文件目录,看看对不对!
|
1月前
|
Ubuntu Linux Shell
手把手教你安装适用于Linux的Windows子系统——Ubuntu
重启完成,你看看重新打开Ubuntu是不是发生了变化,等待几分钟,系统配置完成,根据提示设置用户名和密码即可
|
1月前
|
存储 Ubuntu Linux
安卓手机免root安装各种Linux系统:Ubuntu, Centos,Kali等
此外还可以安装Slackware、Archstrike等系统,还可以通过github查找方法安装更多有趣的东西。 昨日小编就是通过Termux安装的Kali Linux工具包。