注:因为第一次写博客,所以可能有点啰嗦。
前言:
简单学过c++和数据库原理但是随着时间已经忘记了不少东西,这是我重新学习起C++和MYSQL的第一个小项目,因为有点懒没有把函数声明放到头文件里,创建的类没怎么使用,重复的局部变量和函数有点多,有些东西也弄得比较繁琐,另外内存分配和资源释放可能也做的不够好。
因为只是简单的重新学习了C++和SQL语句,里面用到的内容都比较简单,新手入门可以看看。如果还有其他不足,如编程习惯和规范不足等需要改进的东西,希望大佬们指正,谢谢。
背景:
简单重新学习C++后发现想链接MYSQL做个小程序,因为之前没有做过。设想是将一个预设格式的配置文本文件 Student1.txt 的内容读入, 在创建表之后将文本里的内容读入数据库。然后在VC里实现数据库的增删改查, 最终在按0退出程序的时候(按打叉退出不会保存),将数据库的操作完成之后的数据存入另外一个文件 Student2.txt 中。(未保存进入原文件,有怕使文件数据丢失损坏的成分)
追加:MySQL的配置和安装方法CSDN 上面有很多,所以我就不多说了,本来想做一个傻瓜攻略把MySQL的配置也一起讲了的,但是发现有点没那个精力。
值得注意的:
1.环境变量的添加
2.MySQL与Visual Studio连接时包含目录和库目录等
3.配置的时候看好自己安装的MySQL位数,要和VS配置设置时位数保持一致,编译调试时也要使用相同位数
4.MYSQL.h和定义MySQL 结构体时很多东西都要大写,否则编译器可能不认识。(这点最容易吃亏的是全体注释之后取消注释的时候ctrl+U会同时把大写的MYSQL变成小写,如果经常使用全体注释建议吧ctrl+U的变小写给他去掉)
代码部分:
1.主要函数:
void ShowMean(); // 菜单功能 bool ConnectMysql(MYSQL& mysql); // 连接数据库 //void Read(MYSQL& mysql); // 将数据读入并显示 void Query(MYSQL& mysql); // 查询学生数据 void Modify(MYSQL& mysql); // 修改学生数据 void Insert(MYSQL& mysql);// 添加学生信息 void Delete(MYSQL& mysql); // 删除学生数据 void FileIn(MYSQL& mysql); // 读入文本文件并建立数据库内对应表格,并插入文本之中 的数据 int getLine();// 获取文本文件的行数,用以确定建表插入的数据数量 void FileOut(MYSQL& mysql); // 将数据库中文件另行输出到另一个文本文件以备份数据 void createTable(MYSQL& mysql);
2.主函数实现:
根据用户选项进行各个函数的调用,且每次操作完成之后会进行一个界面的清空,让人看着更加舒服。
int main()
{
MYSQL mysql; // 创建数据库结构体
mysql_init(&mysql); //初始化数据库
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 设定数据库字符集
int choice = 1;
if (ConnectMysql(mysql) == false)
{
return 0;
}
else
while (choice != 0) {
ShowMean();
cin >> choice;
switch (choice) {
case 1:
FileIn(mysql); break;
case 2:
Query(mysql); break;
case 3:
Modify(mysql); break;
case 4:
Insert(mysql); break;
case 5:
Delete(mysql); break;
case 0:
FileOut(mysql); exit(0);
default:
cout << "您的输入有误,请重新输入" << endl; break;
}
cout << endl << "操作已完成" << endl;
system("pause");
system("cls");
}
mysql_close(&mysql);
system("pause");
return 0;
}
3.部分实现:
(1)创建表
其实这里可以同时创建一个数据库,但是我没有实现,只要把后边增删改查的指令改成SQL 语句的创建数据库应该就可以实现,有兴趣的可以自己的去实现。重要的一点是创建表的时候要同时设置表的字符集格式,避免汉字乱码。但是两天前我同样设置了字符集但是还是乱码,但是后面不知道怎么回事就突然好了,挺离谱的。
void createTable(MYSQL& mysql) {
// 字符数组内容为MYSQL语句 创建表格
// 记住此处 ` 不是单引号 ' 否则无法创建表格
char Quest[] = "CREATE TABLE IF NOT EXISTS `Student1`(
`Id` int AUTO_INCREMENT,
`name` varchar(20),
`score` double,
PRIMARY KEY (`Id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;"; // 设定表的字符集,避免汉字乱码
//mysql_query(&mysql, "SET CHARACTER SET GBK");
int re = mysql_query(&mysql, Quest);
if (re == 0)
cout << "表格已经创建" << endl;
}
(2)连接数据库
个人认为这部分很重要,尽可能了解连接的语句,很重要的基础
bool ConnectMysql(MYSQL& mysql) {
const char db_Username[] = "root"; // 数据库用户名
const char db_Password[] = "0927"; // 相应的密码
const char db_Host[] = "localhost"; // 数据库连接地址
const char db_Name[] = "sp"; // 数据库名字
unsigned long db_Port = 3306; // 端口号 *此处应注意端口号数据类型和其他四个不同
mysql_init(&mysql); // mysql的API接口,用以初始化数据库
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 将数据库字符集设置为gbk,以避免中文乱码
//开始连接数据并判断是否连接成功;
if (mysql_real_connect(&mysql, db_Host, db_Username, db_Password, db_Name, db_Port, NULL, 0) == NULL)
{
cout << "连接数据库失败,请检查数据是否正确" << endl;
return false;
}
cout << "连接成功" << endl;
createTable(mysql);
return true;
}
(3)查询函数
这里有个遗憾就是没能完成一个查不到就告诉用户没有相关学生,还有增删改查共同的遗憾,输入SQL语句进行增删改查,我也没去实现,从实现的可能性和难度上来说应该是有可能简单实现的。
void Query(MYSQL& mysql) // 查询学生数据
{
MYSQL_RES* res; // 创建一个结果集
MYSQL_ROW row; // 二维数组存放记录
cout << "您选择了查询学生信息" << endl;
cout << "请输入您要查询的选项" << endl;
cout << "t 1. 查询全部学生" << endl;
cout << "t 2. 按学号查询" << endl;
cout << "t 3. 按照名字进行查询" << endl;
cout << "t 4. 按照分数进行查询" << endl;
//cout << "t 5.自定义SQL命令进行查询" << endl;
int choice;
string sql;
cin >> choice;
switch (choice) {
case 1:
{
cout << "全体学生信息如下:" << endl;
sql = "select * from student1 order by Id";
cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句
mysql_query(&mysql, sql.c_str());
break;
}
case 2:
{
cout << "请输入要查询的学生学号" << endl;
int Id;
cin >> Id;
sql = "select * from student1 where Id = " + to_string(Id) + " order by Id";
cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句
mysql_query(&mysql, sql.c_str());
break;
}
case 3:
{
cout << "请输入要查询的学生姓名" << endl;
string name;
cin >> name;
sql = "select * from student1 where name = '" + name + "' order by Id";
cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句
mysql_query(&mysql, sql.c_str());
break;
}
case 4:
{
cout << "请输入要查询的学生分数" << endl;
int score;
cin >> score;
sql = "select * from student1 where score = " + to_string(score) + " order by Id";
cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句
mysql_query(&mysql, sql.c_str());
break;
}
//case 5:
//{
// cout << "请输入SQL命令语句" << endl;
// cin >> sql;
// cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句
// mysql_query(&mysql, sql.c_str());
// break;
//}
default:
cout << "输入有误请重试" << endl;
}
cout << "tt查询结果如下" << endl;
res = mysql_store_result(&mysql); // 将查询得到的数据存入结果集
if (res == NULL)
cout << "所有学生均与你查询的数据不匹配" << endl;
else {
cout << "t学号t" << "t姓名t" << "t得分t" << endl;
while (row = mysql_fetch_row(res))
{
cout << "t" << row[0] << "tt" << row[1] << "tt" << row[2] << endl;
}
}
mysql_free_result(res);
}
其他的函数我就不一一赘述了,到总代码里面看吧。
文件格式图
(数据结束之后还有一行空行)
程序部分展示
总代码:
#define _CRT_SECURE_NO_WARNINGS #pragma once; #include#include #include #include #include #include #include using namespace std; class Student { private: int m_Id; string m_Name; int m_Score; public: int getId() { return m_Id; } string getName() { return m_Name; } int getScore() { return m_Score; } void setId(int& Id) { m_Id = Id; } void setName(string& name) { m_Name = name; } void setScore(int score) { m_Score = score; } }; void ShowMean(); // 菜单功能 bool ConnectMysql(MYSQL& mysql); // 连接数据库 //void Read(MYSQL& mysql); // 将数据读入并显示 void Query(MYSQL& mysql); // 查询学生数据 void Modify(MYSQL& mysql); // 修改学生数据 void Insert(MYSQL& mysql);// 添加学生信息 void Delete(MYSQL& mysql); // 删除学生数据 void FileIn(MYSQL& mysql); // 读入文本文件并建立数据库内对应表格,并插入文本之中 的数据 int getLine();// 获取文本文件的行数,用以确定建表插入的数据数量 void FileOut(MYSQL& mysql); // 将数据库中文件另行输出到另一个文本文件以备份数据 void createTable(MYSQL& mysql); int main() { MYSQL mysql; // 创建数据库结构体 mysql_init(&mysql); //初始化数据库 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 设定数据库字符集 int choice = 1; if (ConnectMysql(mysql) == false) { return 0; } else while (choice != 0) { ShowMean(); cin >> choice; switch (choice) { case 1: FileIn(mysql); break; case 2: Query(mysql); break; case 3: Modify(mysql); break; case 4: Insert(mysql); break; case 5: Delete(mysql); break; case 0: FileOut(mysql); exit(0); default: cout << "您的输入有误,请重新输入" << endl; break; } cout << endl << "操作已完成" << endl; system("pause"); system("cls"); } mysql_close(&mysql); system("pause"); return 0; } void ShowMean() // 展示功能菜单并让用户选择功能 { cout << endl << "=========================================欢迎使用学生管理系统========================================" << endl << endl;; cout << "请选择您要进行的操作" << endl; cout << "t 1. 读取学生数据并显示" << endl; cout << "t 2. 查询学生数据" << endl; cout << "t 3. 修改学生数据" << endl; cout << "t 4. 添加学生数据" << endl; cout << "t 5. 删除学生数据" << endl; cout << "t 0. 退出管理系统" << endl; } void createTable(MYSQL& mysql) { // 字符数组内容为MYSQL语句 创建表格 // 记住此处 ` 不是单引号 ' 否则无法创建表格 char Quest[] = "CREATE TABLE IF NOT EXISTS `Student1`( `Id` int AUTO_INCREMENT, `name` varchar(20), `score` double, PRIMARY KEY (`Id`) )ENGINE=InnoDB DEFAULT CHARSET=utf8;"; // 设定表的字符集,避免汉字乱码 //mysql_query(&mysql, "SET CHARACTER SET GBK"); int re = mysql_query(&mysql, Quest); if (re == 0) cout << "表格已经创建" << endl; } bool ConnectMysql(MYSQL& mysql) { const char db_Username[] = "root"; // 数据库用户名 const char db_Password[] = "0927"; // 相应的密码 const char db_Host[] = "localhost"; // 数据库连接地址 const char db_Name[] = "sp"; // 数据库名字 unsigned long db_Port = 3306; // 端口号 *此处应注意端口号数据类型和其他四个不同 mysql_init(&mysql); // mysql的API接口,用以初始化数据库 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 将数据库字符集设置为gbk,以避免中文乱码 //开始连接数据并判断是否连接成功; if (mysql_real_connect(&mysql, db_Host, db_Username, db_Password, db_Name, db_Port, NULL, 0) == NULL) { cout << "连接数据库失败,请检查数据是否正确" << endl; return false; } cout << "连接成功" << endl; createTable(mysql); return true; } int getLine() { int n = 0; ifstream infile("student2.txt", ios::in); char c; while ( infile.get(c) ) //get函数第一行乱码 { if (c == 'n') n++; } cout << "数据行数为" << n-1 << endl;//实际行数为n+1行此处第一行汉字说明不计为数据行数,数据后有另外一空行 return n; } void FileIn(MYSQL& mysql) //将文本文件读入 { int n = getLine(); cout << "你选择了读入学生信息" << endl; cout << "已存学生数据如下:" << endl; mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 将数据库字符集设置为gbk,以避免中文乱码 ifstream infile("student2.txt", ios::in); const int N = 300; // 默认目前存储数据小于100条(三个数据合起来算一条) const int N2 = 100; string temp[N]; Student student[N2]; // 学生的对象数组用以保存各项数据 int x = 0; int tempId; // 暂时保存取出的值并且为对象赋值 int tempScore; if (!infile.is_open()) { cout << "文件打开失败请确认文件名是否正确" << endl; exit(0); //读取失败直接关闭程序 防止内存冲突程序死掉 } else char line[256] = { 0 }; for (int i = 0; i < N;) // 常犯错误:for循环()里面必须有两个分号;无论几个条件(报错之后自己找了好久才记起来这一点) { while (!infile.eof() &&i < N) //get函数第一行乱码 { for (int j = i; j < i + 3; j++) { infile >> temp[j]; cout << "tt" << temp[j] << "t"; } tempId = atoi(temp[i].c_str()); // 将string类转换为char之后在转换为整形 tempScore = atoi(temp[i + 2].c_str()); student[x].setId(tempId); student[x].setName(temp[i + 1]); student[x].setScore(tempScore); // 这里用了对象数组来做,但其实这个程序的简单功能甚至可以不用到类 cout << endl; x++; i = i + 3; } infile.close(); break; } //mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk"); // 设定数据库字符集 //mysql_query(&mysql, "SET CHARACTER SET GBK"); cout << "插入数据库的命令如下:" << endl; for (int i = 1; i < n; i++) { string sql = "insert into Student1 values (" + to_string(student[i].getId()) + "," + "'" + student[i].getName() + "'" + "," + to_string(student[i].getScore()) + ")"; cout << sql << endl; // 检查语句 mysql_query(&mysql, sql.c_str()); } //mysql_query(&mysql, "insert into Student1 values(1,'李白',99)"); } void FileOut(MYSQL& mysql) // 所有操作完成之后调用,将数据库中的所有数据按照相应格式存入文本文件以备份数据 { MYSQL_RES* res; // 创建一个结果集 MYSQL_ROW row; // 二维数组存放记录 ofstream outfile("student2.txt", ios::out); mysql_query(&mysql, "select * from student1 order by Id"); // 连接成功则查询数据 res = mysql_store_result(&mysql); // 将查询得到的数据存入结果集 cout << "操作结束,所有数据如下:" << endl; cout << "t学号tt" << "姓名tt" << "得分t" << endl; outfile << "学号t" << "名字t" << "得分t" << endl; while (row = mysql_fetch_row(res)) { cout << "t" << row[0] << "tt" << row[1] << "tt" << row[2] << endl; outfile << row[0] << "t" << row[1] << "t" << row[2] << endl; } cout << "他们将被保存到Student2.txt中" << endl; outfile.close(); mysql_free_result(res); } //void Read(MYSQL& mysql) // 将数据读入并显示 //{ // // cout << "你选择了读入学生信息" << endl; // // cout << "已存学生数据如下:" << endl; // // //FileIn(); // //} void Query(MYSQL& mysql) // 查询学生数据 { MYSQL_RES* res; // 创建一个结果集 MYSQL_ROW row; // 二维数组存放记录 cout << "您选择了查询学生信息" << endl; cout << "请输入您要查询的选项" << endl; cout << "t 1. 查询全部学生" << endl; cout << "t 2. 按学号查询" << endl; cout << "t 3. 按照名字进行查询" << endl; cout << "t 4. 按照分数进行查询" << endl; //cout << "t 5.自定义SQL命令进行查询" << endl; int choice; string sql; cin >> choice; switch (choice) { case 1: { cout << "全体学生信息如下:" << endl; sql = "select * from student1 order by Id"; cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句 mysql_query(&mysql, sql.c_str()); break; } case 2: { cout << "请输入要查询的学生学号" << endl; int Id; cin >> Id; sql = "select * from student1 where Id = " + to_string(Id) + " order by Id"; cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句 mysql_query(&mysql, sql.c_str()); break; } case 3: { cout << "请输入要查询的学生姓名" << endl; string name; cin >> name; sql = "select * from student1 where name = '" + name + "' order by Id"; cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句 mysql_query(&mysql, sql.c_str()); break; } case 4: { cout << "请输入要查询的学生分数" << endl; int score; cin >> score; sql = "select * from student1 where score = " + to_string(score) + " order by Id"; cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句 mysql_query(&mysql, sql.c_str()); break; } //case 5: //{ // cout << "请输入SQL命令语句" << endl; // cin >> sql; // cout << "查询的SQL语句如下:" << endl << sql << endl; // 检查语句 // mysql_query(&mysql, sql.c_str()); // break; //} default: cout << "输入有误请重试" << endl; } cout << "tt查询结果如下" << endl; res = mysql_store_result(&mysql); // 将查询得到的数据存入结果集 if (res == NULL) cout << "所有学生均与你查询的数据不匹配" << endl; else { cout << "t学号t" << "t姓名t" << "t得分t" << endl; while (row = mysql_fetch_row(res)) { cout << "t" << row[0] << "tt" << row[1] << "tt" << row[2] << endl; } } mysql_free_result(res); } void Modify(MYSQL& mysql) // 修改学生数据 { int choice; int Id; string name; int score; string sql1; string sql2; string sql; MYSQL_RES *res; MYSQL_ROW row; cout << "您选择了修改学生信息" << endl; cout << "请输入您要修改的学生的信息及数据" << endl; cout << "t 1. 按学号修改" << endl; cout << "t 2. 按名字修改" << endl; cin >> choice; switch (choice) { case 1: { cout << "请输入要修改的学生学号" << endl; cin >> Id; sql = "select * from student1 where Id = " + to_string(Id) + " order by Id"; // sql = "select * from student1 where Id =" + to_string(Id); mysql_query(&mysql, sql.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row == NULL) { cout << "不存在该学号的学生" << endl; break; } else cout << "请输入修改之后的学生姓名" << endl; cin >> name; cout << "请输入修改之后的学生分数" << endl; cin >> score; sql1 = "update Student1 set name= '" + name + "' where Id=" + to_string(Id); sql2 = "update Student1 set score= " + to_string(score) + " where Id=" + to_string(Id); cout << "修改的的SQL语句如下:" << endl << sql1 << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql1.c_str()); mysql_query(&mysql, sql2.c_str()); break; } case 2: { cout << "请输入要修改的学生姓名" << endl; cin >> name; sql1 = "select * from Student1 where name ='" + name+"'"; mysql_query(&mysql, sql1.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row == NULL) { cout << "不存在该姓名的学生" << endl; break; } else cout << "请输入修改之后的学生学号" << endl; cin >> Id; cout << "请输入修改之后的学生分数" << endl; cin >> score; sql1 = "update Student1 set Id= " + to_string(Id) + " where name='" + name + "'"; sql2 = "update Student1 set score= " + to_string(score) + " where name='" + name + "'"; cout << "修改的的SQL语句如下:" << endl << sql1 << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql1.c_str()); mysql_query(&mysql, sql2.c_str()); break; } default: cout << "输入有误请重试" << endl; } //mysql_free_result(res); } void Insert(MYSQL& mysql)//添加学生信息 { int Id; string name; int score; MYSQL_RES* res; // 创建一个结果集 MYSQL_ROW row; // 二维数组存放记录 string sql1; string sql2; cout << "您选择了添加学生信息" << endl; cout << "请输入学生学号" << endl; cin >> Id; sql1 = "select * from student1 where Id = " + to_string(Id) + " order by Id"; mysql_query(&mysql, sql1.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row != NULL) cout << "已存在该学号的学生,系统不允许学号相同,请重新添加或选择修改该学生信息"< > name; cout << "请输入学生得分" << endl; cin >> score; sql2 = "insert into Student1 values (" + to_string(Id) + "," + "'" + name + "'" + "," + to_string(score) + ")"; cout << "插入的SQL语句如下:" << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql2.c_str()); // 使用sql命令对数据库进行数据添加 } mysql_free_result(res); } void Delete(MYSQL& mysql) // 删除学生数据 { int choice = 1; int Id; string name, sql1, sql2; int score; MYSQL_RES * res; MYSQL_ROW row; cout << "您选择了删除学生信息" << endl; //cout << "请输入您要删除的学生信息" << endl; cout << "t 1. 按学号删除" << endl; cout << "t 2. 按名字删除" << endl; cout << "t 3. 按照分数删除" << endl; cin >> choice; switch (choice) { case 1: { cout << "请输入该生学号" << endl; cin >> Id; sql1 = "select * from Student1 where Id =" + to_string(Id); mysql_query(&mysql, sql1.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row == NULL) { cout << "不存在该学号的学生" << endl; break; } else sql2 = "delete from Student1 where Id= " + to_string(Id); cout << "删除的SQL语句如下:" << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql2.c_str()); break; } case 2: { cout << "请输入该生姓名" << endl; cin >> name; sql1 = "select * from Student1 where name ='" + name+"'"; mysql_query(&mysql, sql1.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row == NULL) { cout << "不存在该姓名的学生" << endl; break; } else sql2 = "delete from Student1 where name= '" + name + "'"; cout << "删除的SQL语句如下:" << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql2.c_str()); break; } case 3: { cout << "您确定要使用分数来删除信息吗,该操作可能会影响多名学生" << endl; cout << "1.确定t 2.取消" << endl; int c = 0; cin >> c; if (c != 1) { cout << "您选择了取消操作" << endl; break; } else cout << "您依旧选择了使用分数删除信息!" << endl; cout << "请选择要删除的分数" << endl; cin >> score; sql1 = "select * from Student1 where score =" + to_string(score); mysql_query(&mysql, sql1.c_str()); res = mysql_store_result(&mysql); row = mysql_fetch_row(res); if (row == NULL) { cout << "不存在该分数的学生" << endl; break; } else sql2 = "delete from Student1 where score= " + to_string(score); cout << "删除的SQL语句如下:" << endl << sql2 << endl; // 检查语句 mysql_query(&mysql, sql2.c_str()); break; } default: cout << "您输入的选项有误,请重新输入" << endl; } }



