Linux下编写C++服务器(MySQL连接)

安装MySQL

网上有很多从yum下载安装的教程,但是不知道什么原因下载速度很慢,速度在10k/s以内,这里是参照CentOS 7离线安装MySQL 5.7下载的,操作比较复杂,但速度会快一点,觉得麻烦可以直接在yum下载。
安装完MySQL服务器后,我的C++程序使用MySQL的include和lib目录连接不上数据库,后面安装一个叫mysql-devel的一个驱动,并使用它的include和lib才连接成功,安装方法很简单,在终端输入

yum install mysql-devel

就可以安装了。

配置环境

  1. 安装完成后,会出现/usr/include/mysql和/usr/lib64/mysql,这里面包含了我们需要的头文件和库。
    把/usr/local/mysql/include/放到windows的共享目录下,并改名为mysql;
cp -r /usr/local/mysql/include/ /mnt/hgfs/LinuxShare/
mv /mnt/hgfs/LinuxShare/include/ /mnt/hgfs/LinuxShare/mysql
  1. 创建一个名为databaseTest的Makefile项目;
  2. 右键项目,选择属性,在GeneralRemote Build Root Directory中写入Linux上的项目目录,
    在这里插入图片描述
    C++->Include Search Path添加E:\LinuxShare\include;E:\LinuxShare\include\c++\4.8.2;E:\LinuxShare\mysql;
    在这里插入图片描述
    Remote Build四项中分别写入
cd $(RemoteRootDir)/$(ProjectName); make build
cd $(RemoteRootDir)/$(ProjectName); make clean build
cd $(RemoteRootDir)/$(ProjectName); make clean
$(RemoteRootDir)/$(ProjectName)/dbTest

如图:
在这里插入图片描述

  1. 在项目下添加main.cppMysqlop.hMysql.cppMakefile
    在这里插入图片描述
    这里我已经对SQL的操作进行了封装,
    Mysqlop.h
#pragma once

#include <mysql.h>
#include <errmsg.h>
#ifndef MYSQL_SUCCESSED
#define MYSQL_SUCCESSED			0					// 执行成功
#define MYSQL_CONNECT_NULL		CR_MAX_ERROR + 1	// 连接为空
#define MYSQL_MEMORY_ERROR		CR_MAX_ERROR + 2	// 内部存储空间不够
#define MYSQL_CONNECT_FAIL		CR_MAX_ERROR + 3	// sqlconnect失败
#define MYSQL_INIT_FAIL			CR_MAX_ERROR + 4	// sqlinit失败,一般为内存不够
#define MYSQL_QUERY_NEW_FAIL	CR_MAX_ERROR + 5	// sqlquery语句过长,动态申请空间不够
#define MYSQL_QUERY_MEMORY_FAIL	CR_MAX_ERROR + 6	// sqlquery语句过长,动态申请空间失败
#define MYSQL_CONTINUE			CR_MAX_ERROR + 7	// sql错误中断,但仍然可以继续
#define MYSQL_NOT_CONTINUE		CR_MAX_ERROR + 8	// sql错误中断,不可继续
#define MYSQL_SELCTDB_ERROR		CR_MAX_ERROR + 9	// 选择数据库失败
#define MYSQL_UNKNOWN_ERROR		CR_MAX_ERROR + 10	// 其它未知错误,可能是内部存储空间不够
#endif

class Mysqlop
{
public:
	Mysqlop();
	~Mysqlop();

protected:
	char ip[64];
	char username[256];
	char passwd[256];
	char dbname[256];
	unsigned int port;
	MYSQL* sql;
	char errmsg[1024];

public:
	int sqlconnect(const char* ip, unsigned int port, const char* username, const char* passwd, const char* dbname);
	int sqlconnect(void);
	bool isconnected(void);

	//选择修改数据库
	int sqlselectdb(const char*  dbname);
	int sqlselectdb(void);
	
	int sqlquery(const char* query);
	int sqlclose(void);
	unsigned long getinsertid(void);
	unsigned long sqlnumrows(MYSQL_RES* res);

	MYSQL_RES* sqlstoreresult(void);
	MYSQL_ROW sqlfetchrow(MYSQL_RES* sqlRes);
	void sqlfreeresult(MYSQL_RES* result);

	//测试数据库联通性,用于登录前的验证
	int testsqlconnect(const char* ip, unsigned int port, const char* username, const char* passwd, const char* dbname);

	char* geterrmsg();
};

Mysqlop.cpp

#include "Mysqlop.h"
#include <stdio.h>
#include <string.h>
#include <errno.h> 

Mysqlop::Mysqlop()
{
	sql = NULL;
	memset(ip, 0x00, sizeof(ip));
	memset(username, 0x00, sizeof(username));
	memset(passwd, 0x00, sizeof(passwd));
	memset(dbname, 0x00, sizeof(dbname));
	port = 0x00;
}


Mysqlop::~Mysqlop()
{
	if (sql != nullptr)
		sqlclose();
}

int Mysqlop::sqlconnect(const char * ip, unsigned int port, const char * username, const char * passwd, const char * dbname)
{
	if (nullptr == sql){
		sql = mysql_init(NULL);
	}
	if (nullptr == sql){
		snprintf(errmsg, sizeof(errmsg), "MySQL init error: %s\n", mysql_error(sql));
		return MYSQL_INIT_FAIL;
	}

	this->port = port;
	strncpy(this->ip,ip, sizeof(this->ip));
	strncpy(this->username, username, sizeof(this->username));
	strncpy(this->passwd, passwd, sizeof(this->passwd));
	strncpy(this->dbname, dbname, sizeof(this->dbname));

	if (!mysql_real_connect(sql, this->ip, this->username, this->passwd, this->dbname, this->port, NULL, 0)){
		snprintf(errmsg, sizeof(errmsg), "MySQL connect error: %s\n", mysql_error(sql));
		return MYSQL_CONNECT_FAIL;
	}
	else{ 
		char value = 1;
		mysql_options(sql, MYSQL_OPT_RECONNECT, &value);
		return MYSQL_SUCCESSED;
	}
		
}

int Mysqlop::sqlconnect(void)
{
	if (nullptr == sql){
		sql = mysql_init(NULL);
	}
	if (nullptr == sql){
		snprintf(errmsg, sizeof(errmsg), "MySQL init error: %s\n", mysql_error(sql));
		return MYSQL_INIT_FAIL;
	}

	if (this->ip && this->username && this->passwd && this->dbname && this->port > 0){
		if (!mysql_real_connect(sql, this->ip, this->username, this->passwd, this->dbname, this->port, NULL, 0)){
			snprintf(errmsg, sizeof(errmsg), "MySQL connect error: %s\n", mysql_error(sql));
			return MYSQL_CONNECT_FAIL;
		}
		else{
			char value = 1;
			mysql_options(sql, MYSQL_OPT_RECONNECT, &value);
			return MYSQL_SUCCESSED;
		}
	}
	else {
		snprintf(errmsg, sizeof(errmsg), "MySQL connect parameter error\n");
		return MYSQL_MEMORY_ERROR;
	}
}

bool Mysqlop::isconnected(void)
{
	if (nullptr == sql)
		return false;
	//没连会自动重连
	int retCode = mysql_ping(sql);
	if (retCode)
		return false;
	else
		return true;
}

int Mysqlop::sqlselectdb(const char * dbname)
{
	if (sql == nullptr)
		sqlconnect();
	int ret = mysql_select_db(sql, dbname);
	if (ret){
		snprintf(errmsg, sizeof(errmsg), "MySQL select database error: %s\n", mysql_error(sql));
		return MYSQL_SELCTDB_ERROR;
	}
	else
		return MYSQL_SUCCESSED;
}

int Mysqlop::sqlselectdb(void)
{
	if (sql != nullptr)
		sqlclose();

	if (sqlconnect() != MYSQL_SUCCESSED)
		return MYSQL_CONNECT_FAIL;

	int ret = mysql_select_db(sql, dbname);
	if (ret) {
		snprintf(errmsg, sizeof(errmsg), "MySQL select database error: %s\n", mysql_error(sql));
		return MYSQL_SELCTDB_ERROR;
	}
	else
		return MYSQL_SUCCESSED;
}

int Mysqlop::sqlquery(const char * query)
{
	if(query[0] == 0x00)
		return MYSQL_SUCCESSED;
	if (sql == NULL){
		sqlclose();
		sqlconnect();	// 尝试重连
	}

	int retCode = mysql_ping(sql);  
	if (retCode){
		sqlclose();
		sqlconnect();
	}
	
	retCode = mysql_real_query(sql, query, (unsigned long)strlen(query));
	if (retCode){
		snprintf(errmsg, sizeof(errmsg), "MySQL query error: %s\n", mysql_error(sql));
		return MYSQL_UNKNOWN_ERROR;
	}
	else
		return MYSQL_SUCCESSED;
}

int Mysqlop::sqlclose(void)
{
	if (sql != nullptr){
		mysql_close(sql);
		sql = nullptr;
	}
	return MYSQL_SUCCESSED;
}

unsigned long Mysqlop::getinsertid(void)
{
	return (unsigned long)mysql_insert_id(sql);
}

unsigned long Mysqlop::sqlnumrows(MYSQL_RES * res)
{
	return (unsigned long)mysql_num_rows(res);
}

MYSQL_RES * Mysqlop::sqlstoreresult(void)
{
	return mysql_store_result(sql);
}

MYSQL_ROW Mysqlop::sqlfetchrow(MYSQL_RES * sqlRes)
{
	if (!sqlRes) 
		return NULL;
	return mysql_fetch_row(sqlRes);
}

void Mysqlop::sqlfreeresult(MYSQL_RES * result)
{
	mysql_free_result(result);
}

int Mysqlop::testsqlconnect(const char * ip, unsigned int port, const char * username, const char * passwd, const char * dbname)
{
	int ret = 0;

	if (NULL == sql)
	{
		sql = mysql_init(NULL);
	}
	if (NULL == sql)
	{
		return MYSQL_INIT_FAIL;
	}

	this->port = port;
	strncpy(this->ip, ip, sizeof(this->ip));
	strncpy(this->username, username, sizeof(this->username));
	strncpy(this->passwd, passwd, sizeof(this->passwd));
	strncpy(this->dbname, dbname, sizeof(this->dbname));

	//连接数据库
	if (!mysql_real_connect(sql, this->ip, this->username, this->passwd, this->dbname, this->port, NULL, 0)) {
		snprintf(errmsg, sizeof(errmsg), "MySQL connect error: %s\n", mysql_error(sql));
		return MYSQL_CONNECT_FAIL;
	}
	else {
		//连接成功,测试数据库
		ret = mysql_select_db(sql, this->dbname);
		if (ret) {
			sqlclose();	//断开连接
			return MYSQL_SELCTDB_ERROR;
		}
		else {
			sqlclose();	//断开连接
			return MYSQL_SUCCESSED;
		}
	}
}

char * Mysqlop::geterrmsg()
{
	return errmsg;
}

main.cpp

#pragma once
#pragma execution_character_set("utf-8")
#include <iostream>
#include <stdio.h>
#include <string.h>
#include "Mysqlop.h"
int main(int argc, char *argv[])
{
	Mysqlop mysql;
	int ret = MYSQL_SUCCESSED;

	ret = mysql.testsqlconnect("127.0.0.1", 3306, "root", "123456", "test");
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}

	ret = mysql.sqlconnect();
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}
	//创表
	char query[1024] = { 0 };
	strcpy(query, "create table if not exists `student`(\
							`id` int unsigned auto_increment,\
							`name` varchar(100) not null,\
							`age` int unsigned not null,\
							primary key (`id`)\
							)ENGINE=InnoDB DEFAULT CHARSET=utf8;");
	ret = mysql.sqlquery(query);
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}
	//清表
	strcpy(query, "truncate table student;");
	ret = mysql.sqlquery(query);
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}
	//插表
	strcpy(query, "insert into student(name, age)values('张三',12),('李四',13),('小明',15),('小刚',15);");
	ret = mysql.sqlquery(query);
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}
	//查表
	MYSQL_RES *sqlres;
	MYSQL_ROW sqlrow;
	snprintf(query, sizeof(query), "select id,name from student where age=%d;",15 );
	ret = mysql.sqlquery(query);
	if (ret != MYSQL_SUCCESSED) {
		std::cout << mysql.geterrmsg();
		return 0;
	}
	sqlres = mysql.sqlstoreresult();
	while ((sqlrow = mysql.sqlfetchrow(sqlres)) != NULL)
	{
		if (sqlrow[0] && sqlrow[1])
		{
			std::cout << "id:" << sqlrow[0] << ",姓名:" << sqlrow[1] << std::endl;
		}
	}
	mysql.sqlfreeresult(sqlres);
	mysql.sqlclose();
	return 0;
}

Makefile

INCLUDEPATH=/usr/include/mysql
LIBPATH=/usr/lib64/mysql
CC1=g++

build:main.o Mysqlop.o
	$(CC1) -gdwarf-2 -o dbTest main.o Mysqlop.o -std=c++11 -I $(INCLUDEPATH) -L $(LIBPATH) -lmysqlclient

main.o:main.cpp Mysqlop.h
	$(CC1) -gdwarf-2 -c main.cpp -std=c++11 -I $(INCLUDEPATH) -L $(LIBPATH) -lmysqlclient

Mysqlop.o:Mysqlop.cpp Mysqlop.h
	$(CC1) -gdwarf-2 -c Mysqlop.cpp -std=c++11 -I $(INCLUDEPATH) -L $(LIBPATH) -lmysqlclient

clean:
	rm *.o dbTest

运行

在这里插入图片描述

发布了14 篇原创文章 · 获赞 6 · 访问量 3121

猜你喜欢

转载自blog.csdn.net/qq_39554698/article/details/98739440