c++ 写MySql工具类
本文主要总结和记录又本人设计的一个mysql连接工具类SqlPackage。
本工具类提供了常用的sql命令的执行接口,利用本工具类提供的方法能够非常地方便地
在c++代码中实现绝大部分的常用数据库操作。
以下链接是一个使用本工具实现的 学生成绩管理系统案例:
BlackCarDriver/student-manage-system
若初次在c++中使用mysql数据库连接可以参考我的上一篇博客:
c++连接mysql入门
sqlPackage.h
#include<iostream>
#include<string>
#include<vector>
using namespace std;
typedef vector<string> res_row;
class SqlPackage {
private:
static MYSQL conn;
static bool isInit;
MYSQL_RES *res_set;
MYSQL_ROW row;
MYSQL_FIELD *field;
int init();
string query(string ope, int interval);
string getTableHead(MYSQL_RES* res, int interval);
public:
SqlPackage();
~SqlPackage();
void testQuery();
void testExec();
void testOther();
res_row queryRow(string ope);
int exec(string ope);
string makeSql(string format, vector<string> strVec);
int insert(string insertSql);
int login(string id, string password);
void printTable(string ope, int interval=20);
};
sqlPackage.cpp
#pragma once
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<winsock.h>
#include<mysql.h>
#include<vector>
#include"SqlPackage.h"
using namespace std;
#define SCUUEED 1
#define FATAL -1
#define WORNG -2
#define TEACHER 3
#define STUDENT 9
#define MANAGER 27
//config of database connection
const char* host = "localhost";
const char* user = "root";
const char* password = "123456";
const char* database = "school";
const int port = 3306;
//static mumber
MYSQL SqlPackage::conn;
bool SqlPackage::isInit = false;
SqlPackage::SqlPackage(){
int res = init(); //init will return false when connect fall
if (res == FATAL){
exit(1);
}
}
SqlPackage::~SqlPackage(){
mysql_close(&conn);
}
int SqlPackage::init(){
if (isInit){
return SCUUEED;
}
else {
isInit = true;
}
mysql_init(&conn);
bool is_scueed = mysql_real_connect(&conn, host, user, password, database, port, NULL, 0);
if (!is_scueed){
fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&conn));
return FATAL;
}
mysql_query(&conn, "SET NAMES utf8");
printf("Connect database scuueed! \n");
return SCUUEED;
}
// the funtion name with test*() mainly purpose on testing the work of it package function.
void SqlPackage::testQuery(){
string queryStr = "select * from t_account";
string result = query(queryStr, 15);
cout << result << endl;
}
void SqlPackage::testExec(){
string insertStr = "INSERT INTO t_account(id,NAME,TYPE)VALUES('1234571','test2','manager');";
string deleteStr = "delete from t_account where name ='test2'";
string updateStr = "UPDATE t_account SET NAME = 'test2' WHERE id = '1234570'";
int res = exec(updateStr);
if (res == SCUUEED){
puts("scuueed!");
}
else{
puts("Fall!");
}
}
void SqlPackage::testOther(){
}
//query() use to exec a select sql and it will return a string to describe the table you are query.
//you can use interval to set the distant between two column
string SqlPackage::query(string queryStr, int interval){
int status = mysql_query(&conn, queryStr.c_str());
if (status != 0){
return "query error ... \n";
}
res_set = mysql_store_result(&conn);
int count = mysql_num_rows(res_set);
if (count <= 0){
return "no result ... \n";
}
string result = "";
result += getTableHead(res_set, interval);
int colNum = mysql_num_fields(res_set);
while ((row = mysql_fetch_row(res_set)) != NULL){
for (int i = 0; i< colNum; i++){
string tmp = (row[i] != NULL ? row[i] : "NULL");
tmp.resize(interval, ' ');
result += tmp;
}
result += "\n";
}
mysql_free_result(res_set);
return result;
}
//queryRow() user to exec some sql that only return a row of result, such as select count(*)
res_row SqlPackage::queryRow(string queryStr){
res_row result;
int status = mysql_query(&conn, queryStr.c_str());
if (status != 0) {
cout << "query row error ... \n";
return result;
}
res_set = mysql_store_result(&conn);
int count = mysql_num_rows(res_set);
if (count == 0){
cout << "no result ... ";
return result;
}
row = mysql_fetch_row(res_set);
for (int i = 0; i< mysql_num_fields(res_set); i++){
string tmp = (row[i] != NULL ? row[i] : "NULL");
result.push_back(tmp);
}
return result;
}
//getTableHead return the name of columns, it is a private function used by query()
string SqlPackage::getTableHead(MYSQL_RES* res, int interval){
string tableHead = "";
int colNum = mysql_num_fields(res);
MYSQL_FIELD* field = mysql_fetch_fields(res);
for (int i = 0; i < colNum; i++){
string colName = field[i].name;
colName.resize(interval, ' ');
tableHead += colName;
}
tableHead += "\n";
string tmp = "-";
tmp.resize(interval*colNum, '-');
tableHead += tmp;
tableHead += "\n";
return tableHead;
}
//exec() mainly execu some sql command that just return scuueed or fatal.
//you can use it to execu insert, delete update command and so on..
int SqlPackage::exec(string ope){
if (mysql_query(&conn, ope.c_str())){
return FATAL;
}
return SCUUEED;
}
//it function used by main(), you can identify user type by the return result
int SqlPackage::login(string id, string password){
int result = WORNG;
string loginTemplace = "select type from t_account where id = '$1' and password = '$2'";
string loginSql = makeSql(loginTemplace, { id, password });
res_row res = queryRow(loginSql);
if (res.size() >0){
cout << res[0] << endl;
if (res[0] == "teacher") result = TEACHER;
if (res[0] == "student") result = STUDENT;
if (res[0] == "manager") result = MANAGER;
}
else{
puts("Password worng or account not exist...");
result = WORNG;
}
return result;
}
//it is a userful function, format is the template of a sql, strVec is the container of args
string SqlPackage::makeSql(string format, vector<string> strVec){
string result = format;
for (int i = 0; i < strVec.size(); i++){
string target = "$" + to_string(i + 1);
auto p = result.find(target);
result = result.replace(p, 2, strVec[i]);
}
return result;
};
//printTable is used to execute some selete command that you are sure it will not go worng
void SqlPackage::printTable(string ope, int interval){
string table = query(ope, interval);
cout << table;
}
int SqlPackage::insert(string insertSql){
int result = exec(insertSql);
return result;
}