基本流程
- 使用mysql_init()初始化连接
- 使用mysql_real_connect()建立一个到mysql数据库的连接
- 使用mysql_query()执行查询语句
- result = mysql_store_result(mysql)获取结果集
- mysql_num_fields(result)获取查询的列数,mysql_num_rows(result)获取结果集的行数
- 通过mysql_fetch_row(result)不断获取下一行,然后循环输出
- 释放结果集所占内存mysql_free_result(result)
- mysql_close(conn)关闭连接
MYSQL *mysql_init(MYSQL *mysql) //出错返回NULL
MYSQL *mysql_real_connect(MYSQL *mysql,const char *host,const char *user,const char *passwd,const char *db,unsigned int port,const char *unix_socket,unsigned long client_flag) //出错返回NULL,并设置Mysql_error
intmysql_query(MYSQL *mysql,const char *stmt_str) //出错返回非0
MYSQL_RES *mysql_store_result(MYSQL *mysql) //返回NULL代表出错或无结果(mysql_errno(mysql)为0)
unsigned intmysql_num_fields(MYSQL_RES *result)
MYSQL_ROWmysql_fetch_row(MYSQL_RES *result)
voidmysql_free_result(MYSQL_RES *result)
c++封装
Mysql.h
#ifndef CLOUD_DISK_MYSQL_H#define CLOUD_DISK_MYSQL_H#include "mysql/mysql.h"#include "Exceptions.h"#include <vector>#include <string>using std::vector;using std::string;class Mysql{public:/*** 创建一个mysql连接对象* @param host host* @param user user* @param password password* @param dbname database name*/Mysql(const char *host,const char *user,const char *password,int port, const char* dbname);/*** 析构函数*/~Mysql() noexcept;/*** 执行一次查询* @param Sql 要执行的sql语句*/void query(const char* Sql);/*** 获取查询的结果数 **用于select*** @return 查询的结果数*/int result_count();/*** query影响的行数 **用于insert,update,delete* @return 影响的行数*/uint64_t affected_rows();/*** 以只读的形式返回查询结果,存放在二维vector中,全部是string形式* @return 以只读的形式返回查询结果,存放在二维vector中,全部是string形式*/const vector<vector<string> >& get_result();/*** 获取某一行的查询结果* @param row 行号(0开始)* @return 该行的查询结果*/const vector<string>& get_row_result(int row);/*** 取出某一字段的全部结果* @param field_name 要取出结果的字段名* @return 该字段的全部查询结果,若字段不存在将抛出MysqlException错误* @throw MysqlException Mysql类的统一异常*/vector<string> get_one_field_all_result(const char* field_name);/*** 根据字段名称获取字段索引号* @param field_name* @return*/// 该函数意义不大// int get_index_by_field(const char* field_name);Mysql(Mysql &)=delete;Mysql& operator=(Mysql&)=delete;private:MYSQL mysql;MYSQL_RES * mysql_result;vector<vector<string> > str_result;MYSQL_FIELD * fields;};#endif //CLOUD_DISK_MYSQL_H
Exceptions.h
//// Created by wanghaitao on 2021/2/4.//#ifndef CLOUD_DISK_EXCEPTIONS_H#define CLOUD_DISK_EXCEPTIONS_H#include <exception>#include <string>#include "mysql/mysql.h"class MysqlException : public std::exception {public:const char * what() const noexcept override;explicit MysqlException(const char* what):_what(what){}explicit MysqlException(MYSQL* mysql):_what(mysql_error(mysql)){}~MysqlException() override =default;private:std::string _what;};#endif //CLOUD_DISK_EXCEPTIONS_H
Mysql.cpp
//// Created by wanghaitao on 2021/2/3.//#include "include/Mysql.h"#include "Exceptions.h"#include <cstring>Mysql::Mysql(const char *host, const char *user, const char *password, int port, const char *dbname) :mysql_result(nullptr),str_result(),fields(nullptr) {if ((mysql_init(&mysql)) == nullptr) {throw MysqlException("memory is not enough");}if ((mysql_real_connect(&mysql, host, user, password, dbname, port, NULL, 0)) == nullptr) {// mysql_close(&mysql);throw MysqlException(&mysql);}}void Mysql::query(const char *Sql) {// 清空上次查询的结果if (!str_result.empty())str_result.clear();if (mysql_result) {mysql_free_result(mysql_result);mysql_result = nullptr;}// 执行sql语句if ((mysql_query(&mysql, Sql)) != 0) {// mysql_close(&mysql);throw MysqlException(&mysql);}if ((mysql_result = mysql_store_result(&mysql)) == nullptr) {if (mysql_errno(&mysql) == 0) // 无查询结果return;elsethrow MysqlException(&mysql);}// 取出结果unsigned int columns = 0, rows_num = 0;MYSQL_ROW row;columns = mysql_num_fields(mysql_result);rows_num = mysql_num_rows(mysql_result);// 去除field字段表fields = mysql_fetch_field(mysql_result);// 取出结果集str_result.resize(rows_num);for (int i = 0; i < rows_num; ++i) {row = mysql_fetch_row(mysql_result);str_result[i].reserve(columns);for (int j = 0; j < columns; ++j) {str_result[i].emplace_back(row[j] ? row[j] : "null");}}}int Mysql::result_count() {return str_result.size();}uint64_t Mysql::affected_rows() {return mysql_affected_rows(&mysql);}const vector<vector<string> > &Mysql::get_result() {return str_result;}const vector<string> &Mysql::get_row_result(int row) {if (row >= str_result.size())throw MysqlException("get row result out of range");return str_result[row];}vector<string> Mysql::get_one_field_all_result(const char *field_name) {int row_nums = str_result.size();if (row_nums == 0)return vector<string>();unsigned int field_nums = str_result[0].size();int i;for (i = 0; i < field_nums; ++i) {if (strcmp(field_name, fields[i].name) == 0) // 匹配到目标字段break;}// 找不到该字段if (i == field_nums)throw MysqlException("no such field");vector<string> field_result;field_result.reserve(row_nums);for (int j = 0; j < row_nums; ++j) {field_result.emplace_back(str_result[j][i]); // i是列号,j是行号}return field_result;}Mysql::~Mysql() noexcept {if (mysql_result != nullptr)mysql_free_result(mysql_result);mysql_close(&mysql);}
Exceptions.cpp
//// Created by wanghaitao on 2021/2/4.//#include "Exceptions.h"const char *MysqlException::what() const noexcept {return _what.c_str();}
