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;
}