基本流程

  • 使用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)关闭连接
  1. MYSQL *
  2. mysql_init(MYSQL *mysql) //出错返回NULL
  1. MYSQL *
  2. mysql_real_connect(MYSQL *mysql,
  3. const char *host,
  4. const char *user,
  5. const char *passwd,
  6. const char *db,
  7. unsigned int port,
  8. const char *unix_socket,
  9. unsigned long client_flag) //出错返回NULL,并设置Mysql_error
  1. int
  2. mysql_query(MYSQL *mysql,
  3. const char *stmt_str) //出错返回非0
  1. MYSQL_RES *
  2. mysql_store_result(MYSQL *mysql) //返回NULL代表出错或无结果(mysql_errno(mysql)为0)
  1. unsigned int
  2. mysql_num_fields(MYSQL_RES *result)
  1. MYSQL_ROW
  2. mysql_fetch_row(MYSQL_RES *result)
  1. void
  2. mysql_free_result(MYSQL_RES *result)

c++封装

Mysql.h

  1. #ifndef CLOUD_DISK_MYSQL_H
  2. #define CLOUD_DISK_MYSQL_H
  3. #include "mysql/mysql.h"
  4. #include "Exceptions.h"
  5. #include <vector>
  6. #include <string>
  7. using std::vector;
  8. using std::string;
  9. class Mysql
  10. {
  11. public:
  12. /**
  13. * 创建一个mysql连接对象
  14. * @param host host
  15. * @param user user
  16. * @param password password
  17. * @param dbname database name
  18. */
  19. Mysql(const char *host,const char *user,const char *password,int port, const char* dbname);
  20. /**
  21. * 析构函数
  22. */
  23. ~Mysql() noexcept;
  24. /**
  25. * 执行一次查询
  26. * @param Sql 要执行的sql语句
  27. */
  28. void query(const char* Sql);
  29. /**
  30. * 获取查询的结果数 **用于select**
  31. * @return 查询的结果数
  32. */
  33. int result_count();
  34. /**
  35. * query影响的行数 **用于insert,update,delete
  36. * @return 影响的行数
  37. */
  38. uint64_t affected_rows();
  39. /**
  40. * 以只读的形式返回查询结果,存放在二维vector中,全部是string形式
  41. * @return 以只读的形式返回查询结果,存放在二维vector中,全部是string形式
  42. */
  43. const vector<vector<string> >& get_result();
  44. /**
  45. * 获取某一行的查询结果
  46. * @param row 行号(0开始)
  47. * @return 该行的查询结果
  48. */
  49. const vector<string>& get_row_result(int row);
  50. /**
  51. * 取出某一字段的全部结果
  52. * @param field_name 要取出结果的字段名
  53. * @return 该字段的全部查询结果,若字段不存在将抛出MysqlException错误
  54. * @throw MysqlException Mysql类的统一异常
  55. */
  56. vector<string> get_one_field_all_result(const char* field_name);
  57. /**
  58. * 根据字段名称获取字段索引号
  59. * @param field_name
  60. * @return
  61. */
  62. // 该函数意义不大
  63. // int get_index_by_field(const char* field_name);
  64. Mysql(Mysql &)=delete;
  65. Mysql& operator=(Mysql&)=delete;
  66. private:
  67. MYSQL mysql;
  68. MYSQL_RES * mysql_result;
  69. vector<vector<string> > str_result;
  70. MYSQL_FIELD * fields;
  71. };
  72. #endif //CLOUD_DISK_MYSQL_H

Exceptions.h

  1. //
  2. // Created by wanghaitao on 2021/2/4.
  3. //
  4. #ifndef CLOUD_DISK_EXCEPTIONS_H
  5. #define CLOUD_DISK_EXCEPTIONS_H
  6. #include <exception>
  7. #include <string>
  8. #include "mysql/mysql.h"
  9. class MysqlException : public std::exception {
  10. public:
  11. const char * what() const noexcept override;
  12. explicit MysqlException(const char* what):_what(what){}
  13. explicit MysqlException(MYSQL* mysql):_what(mysql_error(mysql)){}
  14. ~MysqlException() override =default;
  15. private:
  16. std::string _what;
  17. };
  18. #endif //CLOUD_DISK_EXCEPTIONS_H

Mysql.cpp

  1. //
  2. // Created by wanghaitao on 2021/2/3.
  3. //
  4. #include "include/Mysql.h"
  5. #include "Exceptions.h"
  6. #include <cstring>
  7. Mysql::Mysql(const char *host, const char *user, const char *password, int port, const char *dbname) :
  8. mysql_result(nullptr),
  9. str_result(),
  10. fields(nullptr) {
  11. if ((mysql_init(&mysql)) == nullptr) {
  12. throw MysqlException("memory is not enough");
  13. }
  14. if ((mysql_real_connect(&mysql, host, user, password, dbname, port, NULL, 0)) == nullptr) {
  15. // mysql_close(&mysql);
  16. throw MysqlException(&mysql);
  17. }
  18. }
  19. void Mysql::query(const char *Sql) {
  20. // 清空上次查询的结果
  21. if (!str_result.empty())
  22. str_result.clear();
  23. if (mysql_result) {
  24. mysql_free_result(mysql_result);
  25. mysql_result = nullptr;
  26. }
  27. // 执行sql语句
  28. if ((mysql_query(&mysql, Sql)) != 0) {
  29. // mysql_close(&mysql);
  30. throw MysqlException(&mysql);
  31. }
  32. if ((mysql_result = mysql_store_result(&mysql)) == nullptr) {
  33. if (mysql_errno(&mysql) == 0) // 无查询结果
  34. return;
  35. else
  36. throw MysqlException(&mysql);
  37. }
  38. // 取出结果
  39. unsigned int columns = 0, rows_num = 0;
  40. MYSQL_ROW row;
  41. columns = mysql_num_fields(mysql_result);
  42. rows_num = mysql_num_rows(mysql_result);
  43. // 去除field字段表
  44. fields = mysql_fetch_field(mysql_result);
  45. // 取出结果集
  46. str_result.resize(rows_num);
  47. for (int i = 0; i < rows_num; ++i) {
  48. row = mysql_fetch_row(mysql_result);
  49. str_result[i].reserve(columns);
  50. for (int j = 0; j < columns; ++j) {
  51. str_result[i].emplace_back(row[j] ? row[j] : "null");
  52. }
  53. }
  54. }
  55. int Mysql::result_count() {
  56. return str_result.size();
  57. }
  58. uint64_t Mysql::affected_rows() {
  59. return mysql_affected_rows(&mysql);
  60. }
  61. const vector<vector<string> > &Mysql::get_result() {
  62. return str_result;
  63. }
  64. const vector<string> &Mysql::get_row_result(int row) {
  65. if (row >= str_result.size())
  66. throw MysqlException("get row result out of range");
  67. return str_result[row];
  68. }
  69. vector<string> Mysql::get_one_field_all_result(const char *field_name) {
  70. int row_nums = str_result.size();
  71. if (row_nums == 0)
  72. return vector<string>();
  73. unsigned int field_nums = str_result[0].size();
  74. int i;
  75. for (i = 0; i < field_nums; ++i) {
  76. if (strcmp(field_name, fields[i].name) == 0) // 匹配到目标字段
  77. break;
  78. }
  79. // 找不到该字段
  80. if (i == field_nums)
  81. throw MysqlException("no such field");
  82. vector<string> field_result;
  83. field_result.reserve(row_nums);
  84. for (int j = 0; j < row_nums; ++j) {
  85. field_result.emplace_back(str_result[j][i]); // i是列号,j是行号
  86. }
  87. return field_result;
  88. }
  89. Mysql::~Mysql() noexcept {
  90. if (mysql_result != nullptr)
  91. mysql_free_result(mysql_result);
  92. mysql_close(&mysql);
  93. }

Exceptions.cpp

  1. //
  2. // Created by wanghaitao on 2021/2/4.
  3. //
  4. #include "Exceptions.h"
  5. const char *MysqlException::what() const noexcept {
  6. return _what.c_str();
  7. }