`
sealbird
  • 浏览: 570655 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Linux下使用C/C++访问数据库

    博客分类:
  • C++
阅读更多
Linux下使用C/C++访问数据库——MySQL篇 

        最近打算写一套OA系统,为了方便进行数据库操作,特意抽出一周的时间来研究C/C++访问各种数据库的方法,并打算封装一套数据库操作类,现在奉上最简单的一部分:在Linux下访问MySQL数据库。
        本文中使用的MySQL API代码为C语言,如果各位对C++有兴趣,可以考虑使用mysql++。
一、配置开发环境
首先需要编译、安装MySQL,安装完成后,将MySQL目录中的lib目录添加到环境变量中。
新建C/C++工程,把$MYSQL_ROOT/include添加到编译环境的包含路径下面。在编译选项中,增加$MYSQL_ROOT/lib目录。在Link选项中增加-lmysqlclient(已经把lib目录增加到系统环境变量中),或者直接引用libmysqlclient.so文件。
二、程序代码
不多说了,直接上代码,注释都很详细。
/*    
* MySQLManager.h    
*    
*    Created on: Feb 18, 2009    
*            Author: Steven Wee    
*/    

#ifndef MYSQLMANAGER_H_    
#define MYSQLMANAGER_H_    

#include "../Common/CheckStringTools.h"    

#include <mysql.h>    

#include <string>    
#include <iostream>    
#include <vector>    

#include <string.h>    

using namespace std;    

class MySQLManager    
{    
public:    
        /*    
         * Init MySQL    
         * @param hosts:         Host IP address    
         * @param userName:        Login UserName    
         * @param password:        Login Password    
         * @param dbName:        Database Name    
         * @param port:                Host listen port number    
         */    
        MySQLManager(std::string hosts, std::string userName, std::string password, std::string dbName, unsigned int port);    
        ~MySQLManager();    
        void initConnection();    
        /*    
         * Making query from database    
         * @param mysql:        MySQL Object    
         * @param sql:                Running SQL command    
         */    
        bool runSQLCommand(std::string sql);    
        /**    
         * Destroy MySQL object    
         * @param mysql                MySQL object    
         */    
        void destroyConnection();    
        bool getConnectionStatus();    
        vector< vector<string> > getResult();    
protected:    
        void setUserName(std::string userName);    
        void setHosts(std::string hosts);    
        void setPassword(std::string password);    
        void setDBName(std::string dbName);    
        void setPort(unsigned int port);    
private:    
        bool IsConnected;    
        vector< vector<string> > resultList;    
        MYSQL mySQLClient;    
        unsigned int DEFAULTPORT;    
        char * HOSTS;    
        char * USERNAME;    
        char * PASSWORD;    
        char * DBNAME;    
};    

#endif /* MYSQLMANAGER_H_ */ 

/*    
* MySQLManager.cpp    
*    
*    Created on: Feb 18, 2009    
*            Author: Steven Wee    
*/    
#include "MySQLManager.h"    

MySQLManager::MySQLManager(string hosts, string userName, string password, string dbName, unsigned int port)    
{    
        IsConnected = false;    
        this ->setHosts(hosts);            //    设置主机IP地址    
        this ->setUserName(userName);            //    设置登录用户名    
        this ->setPassword(password);            //    设置登录密码    
        this ->setDBName(dbName);            //    设置数据库名    
        this ->setPort(port);            //    设置端口号    
}    

MySQLManager::~MySQLManager()    
{    
        this ->destroyConnection();    
}    

void MySQLManager::setDBName(string dbName)    
{    
        if ( dbName.empty() )    
        {//        用户没有指定数据库名    
                std::cout << "DBName is null! Used default value: mysql" << std::endl;    
                this ->DBNAME = new char[5];    
                strcpy(this ->DBNAME, "mysql");    
        }    
        else    
        {    
                this ->DBNAME = new char[dbName.length()];    
                strcpy(this ->DBNAME, dbName.c_str());    
        }    
}    

void MySQLManager::setHosts(string hosts)    
{    
        if ( hosts.empty() )    
        {//    用户没有指定数据库IP地址    
                std::cout << "Hosts is null! Used default value: localhost" << std::endl;    
                this ->HOSTS = new char[9];    
                strcpy(this ->HOSTS, "localhost");    
        }    
        else    
        {    
                this ->HOSTS = new char[hosts.length()];    
                strcpy(this ->HOSTS, hosts.c_str());    
        }    
}    

void MySQLManager::setPassword(string password)    
{//    用户没有指定密码    
        if ( password.empty() )    
        {    
                std::cout << "Password is null! Used default value: " << std::endl;    
                this ->PASSWORD = new char[1];    
                strcpy(this ->PASSWORD, "");    
        }    
        else    
        {    
                this ->PASSWORD = new char[password.length()];    
                strcpy(this ->PASSWORD, password.c_str());    
        }    
}    

void MySQLManager::setPort(unsigned int port)    
{//    用户没有指定端口号,使用默认端口号    
        if ( port )    
        {    
                std::cout << "Port number is null! Used default value: 0" << std::endl;    
                this ->DEFAULTPORT = 0;    
        }    
        else    
        {    
                this ->DEFAULTPORT = port;    
        }    
}    

void MySQLManager::setUserName(string userName)    
{//    用户没有指定登录用户名    
        if ( userName.empty() )    
        {    
                std::cout << "UserName is null! Used default value: root" << std::endl;    
                this ->USERNAME = new char[4];    
                strcpy(this ->USERNAME, "root");    
        }    
        else    
        {    
                this ->USERNAME = new char[userName.length()];    
                strcpy(this ->USERNAME, userName.c_str());    
        }    
}    

void MySQLManager::initConnection()    
{    
        if ( IsConnected )    
        {//    已经连接到服务器    
                std::cout << "Is connected to server!" <<std::endl;    
                return;    
        }    
        mysql_init(&mySQLClient);//    初始化相关对象    
        if ( !mysql_real_connect( &mySQLClient, HOSTS, USERNAME, PASSWORD, DBNAME, DEFAULTPORT, NULL, 0) )    
        {//    连接到服务器    
                std::cout << "Error connection to database: %s\n" << mysql_error(&mySQLClient) << std::endl;    
        }    
        IsConnected = true;//    修改连接标识    
}    

bool MySQLManager::runSQLCommand(string sql)    
{    
        if ( !IsConnected )    
        {//    没有连接到服务器    
                std::cout << "Not connect to database!" << std::endl;    
                return false;    
        }    
        if ( sql.empty() )    
        {//    SQL语句为空    
                std::cout << "SQL is null!" << std::endl;    
                return false;    
        }    

        MYSQL_RES *res;    
        MYSQL_ROW row;    

        unsigned int i,j = 0;    

        StringTools stringTools;    
        sql = stringTools.filterString(sql);    

        i = mysql_real_query(&mySQLClient,sql.c_str(),(unsigned int)strlen(sql.c_str()));//    执行查询    
        if ( i )    
        {    
                std::cout << "Error query from database: %s\n" << mysql_error(&mySQLClient) << std::endl;    
                return false;    
        }    
        res = mysql_store_result(&mySQLClient);    
        vector<string> objectValue;    
        while( (row = mysql_fetch_row(res)) )    
        {//    遍历结果集    
                objectValue.clear();    
                for ( j = 0 ; j < mysql_num_fields(res) ; j++ )    
                {    
                        objectValue.push_back(row[j]);    
                }    
                this ->resultList.push_back(objectValue);    
        }    
        mysql_free_result(res);         //free result after you get the result    

        return true;    
}    

vector< vector<string> > MySQLManager::getResult()    
{    
        return resultList;    
}    

void MySQLManager::destroyConnection()    
{    
        mysql_close(&mySQLClient);    
        this ->IsConnected = false;    
}    

bool MySQLManager::getConnectionStatus()    
{    
        return IsConnected;    
} 

三、修改建议
本人在以后的完善中,打算把runSQLCommand(char * sql)函数分解成两个或者三个函数,分别执行select和insert等语句。
在程序中,我并没有强制要求参数必须为const,可能会出现一些安全问题。
本文仅起抛砖引玉的作用,希望有高手可以指点我程序中的问题。

敬请期待下一篇文章:Linux下使用C/C++访问数据库——SQL Server篇



一个例子

#include <iostream>   
#include <string>   
#include <strstream>   
using namespace std;   
  
class CBaseX
      {
      public:
		  int x;
		  CBaseX() { x = 10; }
		  void foo() { printf("CBaseX::foo() x=%d\n", x); }
 };
      class CBaseY
        {
			public:
				int y;
				int* py;
				CBaseY() { y = 20; py = &y; }
				void bar() { printf("CBaseY::bar() y=%d, *py=%d\n", y, *py); 
			}
        };
      class CDerived : public CBaseX, public CBaseY
			{
			public:
				int z;
			 CDerived() { z = 10; }
			 void test() { printf("test z=%d\n", z); }
          };

int main()   
{   
    int n = 65535;   
    strstream ss;   
	    strstream ss1;   
			    strstream ss2;   
    string s;   
	string s1;
	string s2;
    ss << n;   
    ss >> s;   
    cout << s << endl;   
   double t_d = 10.6;
  float t_i= static_cast<float>(t_d);
// cout<<t_i<endl;
  ss1<<t_i;
  ss1>>s1;
  cout << s1 << endl;   

  char* c="iloveyou";

  char * p = reinterpret_cast<char *>(c);//
 ss2<<p;
  ss2>>s2;
    cout << s2 << endl;  
	

       CDerived* pD = new CDerived();
	  //  pD->bar();
        printf("CDerived* pD = %x\n", (int)pD);
          CBaseY* pY = pD; // 成功编译, pY = pD + 4
		//  pY->bar();

		  CBaseY* pD3 = dynamic_cast<CBaseY*>(pD);//

         pD3->bar();

		 	  CDerived* pD4 = static_cast<CDerived*>(pD3);//

         pD4->bar();

		   CBaseY* pD5 = static_cast<CBaseY*>(pD4);//

         pD5->bar();

		  CDerived* pD6 = reinterpret_cast<CDerived*>(pD4);// 出错

         pD6->bar();


        printf("CBaseY* pY = %x\n", (int)pY);
            void* pV1 = pY; //成功编译, pV1 = pY
        printf("void* pV1 = %x\n", (int)pV1);
               // pD2 = pY, 但是我们预期 pD2 = pY - 4
        CDerived* pD2 = static_cast<CDerived*>(pV1);
        printf("CDerived* pD2 = %x\n", (int)pD2);
        // 系统崩溃
		pD2->test();

		

/*
class B {};  
class D: public B {}
void f( B* pb )
{
    D* pd1 = dynamic_cast<D*>(pb); 
    D* pd2 = static_cast<D*>(pb);  
}*/



    return 0;   
}  


/*

dynamic_cast:向下转型
static_cast :这个好用 ,可向上也可向下
reinterpret_cast: 这个还有待进一步体会
const_cast: 这个也要时一步体会真实用法

*/
 
 

分享到:
评论

相关推荐

    Linux下实现C++操作Mysql数据库

    由于工作需要抽出一周的时间来研究C/C++访问各种数据库的方法,并打算封装一套数据库操作类,现在奉上最简单的一部分:在Linux下访问MySQL数据库。

    C/C++笔试题(附答案,华为面试题系列)

    答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern "C"修饰的变 量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调 用C 函数。C++提供了一个C 连接交换指定符号...

    c语言连接达梦MD数据库

    C语言简单的连接达梦数据库,里面代码可行,需要进行简单配置VS2013软件

    informix数据库在linux中的安装以及用java/c/c++访问-附件资源

    informix数据库在linux中的安装以及用java/c/c++访问-附件资源

    Cache Server V1.2.0 嵌入式(实时)内存数据库(linux 32)

    另外Cache Server拥有强大的编程能力,拥有业内功能最强大的内存数据库脚本,使Cache Server不只作为数据的高速缓存服务器,更能够实现复杂的业务逻辑,通过编写数据库脚本和存储过程实现以前通过C/C++编程才能实现...

    Python访问Mysql数据库

    公开,可以把部分程序用C 或C++编写,然后在Python 程序 中使用它们。 (7) 可嵌入性 可以把Python 嵌入C/C++程序,从而向程序用户提供脚 本功能。 (8) 丰富的库 Python 标准库确实很庞大。它可以帮助处理各种...

    开源C++应用服务器:CWSS 0.8.0

    CWSS(C++ Web Service Server)是用于开发、集成、部署和管理大型分布式应用、网络应用和数据库应用的C/C++应用服务器。将C/C++的高效稳定和各种通讯标准(UDP/TCP/HTTP/SOAP等)引入大型网络应用的开发、集成、部署和...

    vim个人配置好的开发环境,支持macosx/linux/windows

    sourceinsight的代码查看功能启用,按下工具栏某个生成符号数据库的图标,就行了,各类跳转和搜索都有图标,快速使用。 注意:gvim 或vim 必须在源码目录下打开才行,他只会查找当前目录下的所有代码来生成。。 ...

    C++设计模式

    , , 完成本书的学习后,您将可以创建多线程GUI应用程序,这些应用程序可以访问数据库和操作XML文件,当然更具有吸引力的是它们可以运行在包括Windows、Linux、Unix和Mac OSX在内的多个平台之上!最令人高兴的是您...

    跨平台的c++连接mysql

    支持跨平台,用c++封装成的数据访问层,目前只支持mysql,可将代码加入工程直接编译,快速实现mysql数据库的访问! 注意:在vc下,需要下载mysql的c库,在linux下,也要下载mysql的c库,并设置。 g++ main.cpp -o ...

    Linux下的IMX6ULL-开发板的第一个APP和驱动实验(三)

    在Linux中,应用程序(App)和驱动程序(Driver)是两个不同的概念和...对于开发应用程序,开发人员通常使用标准的编程语言和工具,如C、C++、Python、Java等,并使用Linux操作系统提供的API和库函数来编写应用程序。

    C++设计模式——基于Qt4开源跨平台开发框架(2008修订版)

    完成本书的学习后,您将可以创建多线程GUI应用程序,这些应用程序可以访问数据库和操作XML文件,当然更具有吸引力的是它们可以运行在包括 Windows、Linux、Unix和Mac OSX在内的多个平台之上!最令人高兴的是您已经...

    sqlite 源码以及帮助

    和The C/C++ Users Journal (March 2004)上的文章吸引了无数程序员。每篇文章发表后, SQLite 网站的访问量都会显著上升。通过这本书你可以看到Mike 的才华和他所做的大量工 作,相信你不会失望。本书包含了关于...

    毕设&课设&项目&实训-基于CRT(远程访问终端)+ARM(GEC)+Linux+C语言的视频监控系统.zip

    包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】...

    MYSQL C API 访问程序

    1. 以下是研究 mysql 5.0.22 得出的结果,描述并使用标准 c++演示了使用 MySQLC API 函数 简单操作数据库的流程; 例子程序在 VC6(VC7.1) + windows 2000 上调试通过; 例子程序在 red hat linux 9,red fc6 上调试通过 ...

    基于C ++ 14/17的HTTP应用程序框架drogon.rar

    *使用基于epoll的非阻塞I / O网络库(macOS / FreeBSD下的kqueue)提供高并发,高性能的网络IO,请访问[TFB测试结果](https://www.techempower。 com / benchmarks /#section = data-r19&hw = ph&test = ...

    gvim开发环境

    sourceinsight的代码查看功能启用,按下工具栏某个生成符号数据库的图标,就行了,各类跳转和搜索都有图标,快速使用。注意:gvim 或vim 必须在源码目录下打开才行,他只会查找当前目录下的所有代码来生成。。安装完...

Global site tag (gtag.js) - Google Analytics