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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 题记:之前项目中使用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;
相关文章
|
5月前
|
Ubuntu Linux
计算机基础知识:linux系统怎么安装?
在虚拟机软件中创建一个新的虚拟机,并选择相应操作系统类型和硬盘空间大小等参数。将下载的 ISO 镜像文件加载到虚拟机中。启动虚拟机,进入安装界面,并按照步骤进行安装。安装完成后,可以在虚拟机中使用 Linux 系统。
|
3月前
|
安全 Linux iOS开发
Nessus Professional 10.10 Auto Installer for RHEL 10, AlmaLinux 10, Rocky Linux 10 - Nessus 自动化安装程序
Nessus Professional 10.10 Auto Installer for RHEL 10, AlmaLinux 10, Rocky Linux 10 - Nessus 自动化安装程序
222 6
Nessus Professional 10.10 Auto Installer for RHEL 10, AlmaLinux 10, Rocky Linux 10 - Nessus 自动化安装程序
|
3月前
|
存储 Linux 开发工具
Linux环境下使用Buildroot配置软件包
使用Buildroot可以大大简化嵌入式Linux系统的开发和维护工作,但它需要对Linux系统和交叉编译有深入的理解。通过上述步骤,可以有效地配置和定制软件包,为特定的嵌入式应用构建高效、稳定的系统。
384 11
|
3月前
|
消息中间件 Kafka Linux
Linux下安装Kafka 3.9.1
本文介绍Kafka 3.9.1版本的安装与配置,包括通过ZooKeeper或KRaft模式启动Kafka。涵盖环境变量设置、日志路径修改、集群UUID生成、存储格式化及服务启停操作,适用于Linux环境下的部署实践。
371 0
|
5月前
|
存储 监控 Linux
Linux环境锁定关键文件防止误删操作流程。
总结以上内容,在Linux环境下锁定重要文档避免误删涉及到多种技术手段与策略组合运作, 包括但不限于利用chatter指挥官固化文档状态至只读模式、运作ACL精准调整访问权利列表、编排自动化流程简
197 20
|
5月前
|
Linux
Linux环境下的UDEV机制及其与守护进程的关联
实际使用时管理员需要熟悉编写合适udev rules去满足特殊需求;同时也需要注意避免编写过度复杂导致无法预料结果rules.UDEVD虽然稳健但错误配置可能导致无法预料问题因此需谨慎处理相关配置工作.
201 16
|
5月前
|
存储 Linux
Linux环境下删除大文件后磁盘空间未释放问题诊断流程。
以上诊断流程涉及Linux底层机制与高级管理技能结合之处,并需要管理员根据实际环境灵活调整诊断策略与解决方案。
366 8
|
5月前
|
网络协议 关系型数据库 Linux
【App Service Linux】在Linux App Service中安装 tcpdump 并抓取网络包
在App Service for Linux环境中,无法像Windows一样直接使用网络排查工具抓包。本文介绍了如何通过TCPDUMP在Linux环境下抓取网络包,包括SSH进入容器、安装tcpdump、执行抓包命令及下载分析文件的完整操作步骤。
256 6

热门文章

最新文章