配置mysql

1 環境配置

這是一篇ubuntu16.04卸載mysql5.7並安裝mysql8.0.19的記錄
ubuntu16.04默認安裝的是mysql5.7的版本

1.1 卸載mysql

sudo apt-get autoremove --purge mysql-server 
sudo apt-get remove mysql-common
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P

// 將mysql的一些沒卸載完的依賴庫自動清除

sudo apt autoremove

1.2 安裝mysql8.0.19

選擇APT安裝,https://dev.mysql.com/downloads/repo/apt/
// 這一步是把MySQL服務器,客戶端和其他組件的APT存儲庫添加到我們的系統的軟件包源列表中
// 可直接選擇默認的配置,選擇好了之後會跳到第一頁,選第一頁的ok選項

sudo dpkg -i mysql-apt-config_0.8.14-1_all.deb 

// 把上一步配置的APT庫更新到系統軟件列表中,否則會下載默認的mysql版本,即5.7

sudo apt-get update

// 安裝MySQL服務器

sudo apt-get install mysql-server

1.3 爲了安全起見,可以增加步驟(也可以不用)

sudo mysql_secure_installation

會出現幾個主要問題:除了基礎的改密碼之外,其他分別是:刪除匿名用戶?禁止遠程root登錄?刪除測試數據庫並訪問它? 現在重新加載特權表?

1.4 查看狀態 開啓 關閉

service mysql status
service mysql start
service mysql stop

2 配置MySQL的c++開發環境

sudo apt-get install libmysqlclient-dev

2.1 查看mysql的頭文件和庫文件路徑

mysql_config --cflags --libs

3 遠程登錄mysql配置

在服務器端登錄:

mysql -u root -p
USE mysql;
UPDATE user SET host = "%" WHERE user = "root";
select host, user from user;

這一步不能少,不然無法遠程登錄

flush privileges;    

3.1 在windows中可能還需要配置防火牆

搜索防火牆,選擇"windows defender 防火牆",點擊“高級設置”,點擊左側"入站規則"後再點擊右側的"新建規則":
選擇“端口”->“下一步”
選擇"TCP"->"特定本地端口"輸入3306->“下一步”
後面選擇默認情況。

3.2 測試,假設服務器IP爲:192.168.106.250

在主機上遠程登錄服務器:

mysql -u root -p -h 192.168.106.250

若服務器沒有密碼:

mysql -u root -h 192.168.106.250

4 一個簡單的c++操作mysql數據庫demo

mysql.pro

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
        main.cpp \
    src/database.cpp

INCLUDEPATH += /usr/include/mysql
LIBS += -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lm -lrt -lssl -lcrypto -ldl

HEADERS += \
    include/database.h

database.h

#ifndef DATABASE_H
#define DATABASE_H

#include <mysql.h>

//tcp
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <unistd.h>
//#include <arpa/inet.h>

#include <string>

using namespace std;


class Database
{
private:
    MYSQL mysql;
    const char *server;   // 服務器地址
    const char *user;     // 用戶名
    const char *pwd;      // 密碼
    const char *basename; // 數據庫名
    int port;             // 端口名
    std::string query;    // 查詢語句
    MYSQL_RES *res;       // 這個結構代表返回行的一個查詢結果集
    MYSQL_ROW result_row; // 用以指向返回結果集中一行的數據
    MYSQL_FIELD *field;   // 用以指向結果集中每一列字段的名稱

    int flag;             // 用來判斷是否需要釋放內存的標誌位
    void free_data();     // 釋放內存


public:
    Database(std::string server = "localhost", std::string user = "root", std::string pwd = "123456",
             std::string basename = "test", int port = 3306);
    ~Database();

    bool ConnectDatabase(); // 連接數據庫

    bool CreateTable(std::string table_name = "facetable", std::string field_name[] = NULL,
                     std::string type[] = NULL, int num = NULL); // 創建表,需要輸入兩個字符串數組,一個是所有名字,另一個是名字對應的類型,還有類別的數量

    bool QueryDatabase(double angle1, double angle1_offset,
                       double angle2, double angle2_offset,
                       double angle3, double angle3_offset,
                       std::string table = "facetable");   // 查詢數據庫,輸入3個角度及其範圍偏移量,表名

    bool QueryDatabase(std::string query = "SELECT * FROM facetable");                    // 用自己的查詢語句查詢數據庫

    bool InsertData(double values[], int size = 5, std::string table_name = "facetable",
                    std::string field_name = "angle1, angle2, angle3, length1, length2"); // 插入一行數據,需要輸入一個保持一行數據的數據,及數組長度

    bool DeleteData(double id, std::string table = "facetable");                          // 輸入要刪除記錄的id號,默認從表"facetable"中刪除

    bool DeleteData(double origin_id, double end_id, std::string table = "facetable");    // 刪除一個範圍內的記錄,包括起點、終點id的記錄

    int GetRows();      // 返回行數

    int GetColumns();   // 返回列數

    void GetData(double ***data);  // 返回二維數組指針

private:
    int rows;             // 返回的結果集的行數
    int columns;          // 返回的結果集的列數(包括了id列)
    double **data;        // 返回的數組
};



#endif // DATABASE_H

databash.cpp

#include "include/database.h"
#include <iostream>
#include <new>
#include <vector>
using namespace std;

Database::Database(std::string server, std::string user, std::string pwd, std::string basename, int port)
{
    this->server   = server.c_str();
    this->user     = user.c_str();
    this->pwd      = pwd.c_str();
    this->basename = basename.c_str();
    this->port     = port;

    flag = 0;


    ConnectDatabase();
}

// 連接數據庫
bool Database::ConnectDatabase()
{
    // 初始化mysql
    mysql_init(&mysql);

    // 連接數據庫,中間分別是主機,用戶名,密碼,數據庫名,端口號
    if (!(mysql_real_connect(&mysql, server, user, pwd, basename, port, NULL, 0)))
    {
        std::cout << "Error connecting to database: " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
    {
        std::cout << "Connect database success!" << std::endl;
    }
}

// 創建表
bool Database::CreateTable(std::string table_name, std::string field_name[], std::string type[], int num)
{
    query.clear();

    if (NULL == num)
    {
        query = "CREATE TABLE " + table_name + "( "
                "id BIGINT NOT NULL AUTO_INCREMENT, "
                "angle1 double NOT NULL, "
                "angle2 double NOT NULL, "
                "angle3 double NOT NULL, "
                "length1 double NOT NULL, "
                "length2 double NOT NULL, "
                "PRIMARY KEY (id) "
                ")ENGINE=InnoDB DEFAULT CHARSET = utf8";
    }
    else
    {
        query = "CREATE TABLE facetable ( "
                "id BIGINT NOT NULL AUTO_INCREMENT, ";
        for (int i = 0; i < num; ++i)
        {
            query += field_name[i] + " " + type[i] + " " + "NOT NULL, ";
        }
        query += "PRIMARY KEY (id) "
                 ")ENGINE=InnoDB DEFAULT CHARSET = utf8";
    }

    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Create table failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
    {
        std::cout << "Create talbe success!" << std::endl;
        return true;
    }


}

// 查詢數據庫
bool Database::QueryDatabase(double angle1, double angle1_offset,
                             double angle2, double angle2_offset,
                             double angle3, double angle3_offset,
                             std::string table)
{
    query.clear();

    // 釋放上一次查詢申請的內存
    if (flag > 0)
        free_data();
    flag += 1;

    // 設置編碼格式,否者cmd下中文亂碼
    mysql_query(&mysql, "SET NAMES utf8");

    // 組合查詢語句
    query = "SELECT * FROM " + table + " WHERE " +
            " angle1 < " + to_string(angle1+angle1_offset) + " AND angle1 > " + to_string(angle1-angle1_offset) +
            " AND angle2 < " + to_string(angle2+angle2_offset) + " AND angle2 > " + to_string(angle2-angle2_offset) +
            " AND angle3 < " + to_string(angle3+angle3_offset) + " AND angle3 > " + to_string(angle3-angle3_offset);

    // 查詢
    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Query failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
    {
        std::cout << "query success!" << std::endl;
    }

    // 獲取結果集
    if (!(res = mysql_store_result(&mysql)))
    {
        std::cout << "Couldn't get result from " << mysql_error(&mysql) << std::endl;
        return false;
    }

    // 打印數據行數(記錄數),列數
    rows    = mysql_num_rows(res);
    columns = mysql_num_fields(res);


    // 動態申請內存
    data = new double*[rows];
    for (int i = 0; i < rows; ++i)
        data[i] = new double[columns];

    // 打印各列字段的類別名稱
//    for (int i = 0; field = mysql_fetch_field(res); ++i)
//        std::cout << field->name << "\t";
//    std::cout << std::endl;

    // 打印結果集中的所有數據
    for (int i = 0; i < rows; ++i)
    {
        // 從結果集中返回下一行所有的字符串
        result_row = mysql_fetch_row(res);
        for (int j = 0; j < columns; ++j)
        {
//            std::cout << result_row[j] << "\t";
            // 將以字符串形式返回的結果集轉換成double型
            data[i][j] = atof(result_row[j]);
//            std::cout << data[i][j] << "\t";
        }
//        std::cout << std::endl;
    }
}

// 查詢數據庫
bool Database::QueryDatabase(std::string query)
{
    // 釋放上一次查詢申請的內存
    if (flag > 0)
        free_data();
    flag += 1;

    // 設置編碼格式,否者cmd下中文亂碼
    mysql_query(&mysql, "SET NAMES utf8");

    // 查詢
    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Query failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
    {
        std::cout << "query success!" << std::endl;
    }

    // 獲取結果集
    if (!(res = mysql_store_result(&mysql)))
    {
        std::cout << "Couldn't get result from " << mysql_error(&mysql) << std::endl;
        return false;
    }

    // 打印數據行數(記錄數),列數
    rows    = mysql_num_rows(res);
    columns = mysql_num_fields(res);

    // 動態申請內存
    data = new double*[rows];
    for (int i = 0; i < rows; ++i)
        data[i] = new double[columns];

    // 打印各列字段的類別名稱
    for (int i = 0; field = mysql_fetch_field(res); ++i)
        std::cout << field->name << "\t";
    std::cout << std::endl;

    // 打印結果集中的所有數據
    for (int i = 0; i < rows; ++i)
    {
        // 從結果集中返回下一行所有的字符串
        result_row = mysql_fetch_row(res);
        for (int j = 0; j < columns; ++j)
        {
//            std::cout << result_row[j] << "\t";
            // 將以字符串形式返回的結果集轉換成double型
            data[i][j] = atof(result_row[j]);
            std::cout << data[i][j] << "\t";
        }
        std::cout << std::endl;
    }
}

// 插入一行記錄
bool Database::InsertData(double values[], int size, std::string table_name, std::string field_name)
{
    query.clear();

    query = "INSERT INTO " + table_name + " (" + field_name + ") VALUES (";

    for (int i = 0; i < size; ++i)
    {
        if (i < size -1)
            query += to_string(values[i]) + ", ";
        else
            query += to_string(values[i]) + ");";
    }

    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Insert failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
    {
        std::cout << "Insert success!" << std::endl;
        return true;
    }
}

// 刪除記錄
bool Database::DeleteData(double id, std::string table)
{
    query.clear();

    query = "DELETE FROM " + table + " WHERE id = " + to_string(id) + ";";

    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Delete failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
        return true;
}

// 刪除範圍內的記錄
bool Database::DeleteData(double origin_id, double end_id, std::string table)
{
    query.clear();

    query += "DELETE FROM " + table + " WHERE id >= " + to_string(origin_id) + " AND id <= " + to_string(end_id) + ";";

    if (mysql_query(&mysql, query.c_str()))
    {
        std::cout << "Delete failed " << mysql_error(&mysql) << std::endl;
        return false;
    }
    else
        return true;
}

// 返回行數
int Database::GetRows()
{
    return rows;
}

// 返回列數
int Database::GetColumns()
{
    return columns;
}


// 返回二維數組指針
void Database::GetData(double ***data)
{
    *data = this->data;
}

// 釋放內存
void Database::free_data()
{
    // 釋放開闢的資源,先釋放列,再釋放行
    for (int i = 0; i < rows; ++i)
        delete[] data[i];
    delete[] data;
//    std::cout << "free success!" << std::endl;
}


// 析構函數
Database::~Database()
{
    if (flag > 0)
        free_data();
}

main.cpp

#include <iostream>
#include "include/database.h"

using namespace std;

int main()
{
    // 演示database類的使用方式
    // 創建對象,有默認參數值,默認主機有一個名叫“test”的數據庫
//    Database mysql("192.168.106.250", "root", "", "test");     // 遠程登錄
    Database mysql("localhost", "root", "123456", "test", 3306); // 登錄本地數據庫
//    Database mysql;

    // 如果數據庫還沒有表,創建表,有默認參數,默認創建一個叫"facetable"的表
//    std::string field_name[] = {"angle1", "angle2", "angle3", "length1", "length2"};
//    std::string name_type[]  = {"double", "double", "double", "double",  "double"};
//    mysql.CreateTable("facetable", field_name, name_type, 5);
    mysql.CreateTable();

    // 往表"facetable"裏插入一行數據(多行可以寫一個for循環)
    double values[] = {10, 20, 30, 5, 6};
//    mysql.InsertData(values, 5, "facetable", "angle1, angle2, angle3, length1, length2");
    mysql.InsertData(values);

    // 查詢數據庫,可以像如下情況自己寫語句
//    std::string query = "SELECT * FROM facetable";
    std::string query = "SELECT * FROM facetable WHERE angle1 > 8 AND angle1 < 12 AND angle2 > 18 AND angle2 < 22 AND angle3 > 28 AND angle3 < 32";
    mysql.QueryDatabase(query);

    // 查詢數據庫
//    mysql.QueryDatabase(values[0], 2, values[1], 2, values[2], 2, "facetable");
    mysql.QueryDatabase(values[0], 2, values[1], 2, values[2], 2);

    // 調用查詢返回的數據,用類成員data,注意:第一列數據是id值,後面5列纔是角度和長度值
    double **data;
    mysql.GetData(&data);
    for (int i = 0; i < mysql.GetRows(); ++i)
    {
        for (int j = 0; j < mysql.GetColumns(); ++j)
            std::cout << data[i][j] << "\t";
        std::cout << std::endl;
    }

    // 刪除id=19的記錄,默認從"facetalbe"表中刪除
//    mysql.DeleteData(19, "facetable");
    mysql.DeleteData(19);


    // 刪除10到30的記錄,包括10和30
//    mysql.DeleteData(10, 30, "facetable");
    mysql.DeleteData(10, 30);

    std::cout << "****************************************" << std::endl;
    mysql.QueryDatabase();

    return 0;
}

發佈了13 篇原創文章 · 獲贊 2 · 訪問量 4872
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章