天天看點

Linux環境下Mysql++安裝及操作深入詳解

題記

之前項目中使用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           

libmysqlclient.so安裝位置檢視:

[root@laoyang testMysqlConn]# rpm -ql mysql-devel
********
/usr/lib64/mysql/libmysqlclient.so           

如上,從結果中可以看到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           

至此,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);
}           

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           

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           

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           

第2步:調試

gdb 可執行檔案 core檔案 
gdb test core.10968           

5、下一步工作

對mysql++如果可能的化,封裝成自己常用的類。目前已經基本相對清晰。

作者:銘毅天下

轉載請标明出處,原文位址:

http://blog.csdn.net/laoyang360/article/details/52335669