一、设计目的
通过该设计,应能理解并掌握C++面向对象,连接数据库的方法,对C++语言有更深刻的理解。
使用clion,以及mysql8.0
二、数据库表
--图书管理系统的数据库建表语句
DROP TABLE IF EXISTS Books;
CREATE TABLE Books (
no INT(7) NOT NULL PRIMARY KEY, -- 图书编号,7位整数
bookName VARCHAR(255) NOT NULL, -- 书名,
author VARCHAR(255) NOT NULL, -- 作者,
publisher VARCHAR(255) NOT NULL, -- 出版社,
price DECIMAL(10,2) NOT NULL, -- 价格,最大1000
category ENUM('文学','科学','自然','名著') NOT NULL -- 分类,限定可选值
)
三、核心代码
#include <iostream>
#include <mysql.h>
#include <string>
using namespace std;
MYSQL *conn;
// 数据库的结果对象
MYSQL_RES *res;
MYSQL_ROW row;
// 验证图书编号是否重复
bool isNoExists(int no)
{
string query = "SELECT COUNT(*) FROM Books WHERE no = " + to_string(no);
mysql_query(conn, query.c_str());
res = mysql_store_result(conn);
row = mysql_fetch_row(res);
int count = atoi(row[0]);
mysql_free_result(res);
return count > 0;
}
// 输入验证函数
int inputNo()
{
cout << "请输入图书编号(编号必须是7位数,并且不可以重复)" << endl;
int no;
cin >> no;
while (no < 1000000 || no > 9999999 || isNoExists(no))
{
if (isNoExists(no))
{
cout << "编号已存在,请重新输入" << endl;
}
else
{
cout << "编号必须是7位数" << endl;
}
cin >> no;
}
return no;
}
// 验证书名输入
string inputbookName()
{
cout << "请输入图书的名称(名称必须1-20字)" << endl;
string bookName;
cin >> bookName;
while (bookName.size() < 1 || bookName.size() > 20)
{
cout << "名字的长度必须是1-20位,请重新输入。" << endl;
cin >> bookName;
}
return bookName;
}
// 验证作者输入
string inputAuthor()
{
cout << "请输入作者的名字(名称必须2-8位)" << endl;
string author;
cin >> author;
while (author.size() < 2 || author.size() > 8)
{
cout << "作者名字的长度必须是2-8位,请重新输入。" << endl;
cin >> author;
}
return author;
}
// 验证出版社输入
string inputPublisher()
{
cout << "请输入出版社名称(名称必须2-20位)" << endl;
string publisher;
cin >> publisher;
while (publisher.size() < 2 || publisher.size() > 20)
{
cout << "出版社的长度必须是2-20位,请重新输入。" << endl;
cin >> publisher;
}
return publisher;
}
// 验证价格输入
double inputPrice()
{
cout << "请输入图书价格(价格1 - 1000)" << endl;
double price;
cin >> price;
while (price < 1 || price > 1000)
{
cout << "价格必须在1-1000之间,请重新输入。" << endl;
cin >> price;
}
return price;
}
// 验证分类输入
string inputCategory()
{
cout << "请输入图书的类别(文学 科学 自然 名著)" << endl;
string category;
cin >> category;
while (category != "文学" && category != "科学" &&
category != "自然" && category != "名著")
{
cout << "图书的类别必须是(文学 科学 自然 名著)之一,请重新输入。" << endl;
cin >> category;
}
return category;
}
// 添加图书
void add()
{
int no = inputNo();
string bookName = inputbookName();
string author = inputAuthor();
string publisher = inputPublisher();
double price = inputPrice();
string category = inputCategory();
// 为字符串进行转义
char escaped_bookName[100];
char escaped_author[100];
char escaped_publisher[100];
char escaped_category[100];
mysql_real_escape_string(conn, escaped_bookName, bookName.c_str(), bookName.length());
mysql_real_escape_string(conn, escaped_author, author.c_str(), author.length());
mysql_real_escape_string(conn, escaped_publisher, publisher.c_str(), publisher.length());
mysql_real_escape_string(conn, escaped_category, category.c_str(), category.length());
// 使用预处理语句
string query = "INSERT INTO Books(no, bookName, author, publisher, price, category) "
"VALUES (?, ?, ?, ?, ?, ?)";
MYSQL_STMT *stmt = mysql_stmt_init(conn);
if (!stmt)
{
cout << "初始化预处理语句失败" << endl;
return;
}
if (mysql_stmt_prepare(stmt, query.c_str(), query.length()))
{
cout << "预处理语句准备失败: " << mysql_stmt_error(stmt) << endl;
mysql_stmt_close(stmt);
return;
}
MYSQL_BIND bind[6];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = &no;
bind[1].buffer_type = MYSQL_TYPE_STRING;
bind[1].buffer = escaped_bookName;
bind[1].buffer_length = strlen(escaped_bookName);
bind[2].buffer_type = MYSQL_TYPE_STRING;
bind[2].buffer = escaped_author;
bind[2].buffer_length = strlen(escaped_author);
bind[3].buffer_type = MYSQL_TYPE_STRING;
bind[3].buffer = escaped_publisher;
bind[3].buffer_length = strlen(escaped_publisher);
bind[4].buffer_type = MYSQL_TYPE_DOUBLE;
bind[4].buffer = &price;
bind[5].buffer_type = MYSQL_TYPE_STRING;
bind[5].buffer = escaped_category;
bind[5].buffer_length = strlen(escaped_category);
if (mysql_stmt_bind_param(stmt, bind))
{
cout << "参数绑定失败: " << mysql_stmt_error(stmt) << endl;
mysql_stmt_close(stmt);
return;
}
if (mysql_stmt_execute(stmt))
{
cout << "添加失败: " << mysql_stmt_error(stmt) << endl;
}
else
{
cout << "添加成功" << endl;
}
mysql_stmt_close(stmt);
}
// 显示图书列表
void list()
{
if (mysql_query(conn, "SELECT * FROM Books"))
{
cout << "查询失败: " << mysql_error(conn) << endl;
return;
}
res = mysql_store_result(conn);
cout << "编号\t书名\t作者\t出版社\t价格\t分类" << endl;
while ((row = mysql_fetch_row(res)))
{
cout << row[0] << "\t" << row[1] << "\t" << row[2] << "\t"
<< row[3] << "\t" << row[4] << "\t" << row[5] << endl;
}
mysql_free_result(res);
}
// 根据编号删除
void delByNo()
{
cout << "输入需要删除图书的编号" << endl;
int no;
cin >> no;
string query = "DELETE FROM Books WHERE no = " + to_string(no);
if (mysql_query(conn, query.c_str()) == 0)
{
if (mysql_affected_rows(conn) > 0)
{
cout << "删除成功" << endl;
}
else
{
cout << "未找到该编号的图书" << endl;
}
}
else
{
cout << "删除失败: " << mysql_error(conn) << endl;
}
}
// 根据书名删除
void delByName()
{
cout << "请输入需要删除的图书名称:" << endl;
string bookName;
cin >> bookName;
string query = "DELETE FROM Books WHERE bookName = '" + bookName + "'";
if (mysql_query(conn, query.c_str()) == 0)
{
int count = mysql_affected_rows(conn);
if (count > 0)
{
cout << "删除成功,本次删除了" << count << "本" << endl;
}
else
{
cout << "未找到该书名的图书" << endl;
}
}
else
{
cout << "删除失败: " << mysql_error(conn) << endl;
}
}
// 删除功能选择
void del()
{
cout << "选择删除方式 1.根据图书编号删除 2.根据图书书名删除" << endl;
int type;
cin >> type;
if (type == 1)
{
delByNo();
}
else if (type == 2)
{
delByName();
}
else
{
cout << "输入错误" << endl;
del();
}
}
// 根据编号查询
void searchByNo()
{
cout << "请输入要查询的图书编号" << endl;
int no;
cin >> no;
string query = "SELECT * FROM Books WHERE no = " + to_string(no);
if (mysql_query(conn, query.c_str()) == 0)
{
res = mysql_store_result(conn);
if ((row = mysql_fetch_row(res)))
{
cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;
cout << row[0] << "\t" << row[1] << "\t" << row[2] << "\t"
<< row[3] << "\t" << row[4] << "\t" << row[5] << endl;
}
else
{
cout << "该编号不存在" << endl;
}
mysql_free_result(res);
}
else
{
cout << "查询失败: " << mysql_error(conn) << endl;
}
}
// 根据书名查询
void searchByName()
{
cout << "请输入要查询的图书名字" << endl;
string bookName;
cin >> bookName;
string query = "SELECT * FROM Books WHERE bookName = '" + bookName + "'";
if (mysql_query(conn, query.c_str()) == 0)
{
res = mysql_store_result(conn);
bool found = false;
while ((row = mysql_fetch_row(res)))
{
if (!found)
{
cout << "\n编号\t书名\t作者\t出版社\t价格\t分类" << endl;
found = true;
}
cout << row[0] << "\t" << row[1] << "\t" << row[2] << "\t"
<< row[3] << "\t" << row[4] << "\t" << row[5] << endl;
}
if (!found)
{
cout << "该图书不存在" << endl;
}
mysql_free_result(res);
}
else
{
cout << "查询失败: " << mysql_error(conn) << endl;
}
}
// 查询功能选择
void searchBook()
{
cout << "请选择查询方式:" << endl;
cout << "1. 按编号查询" << endl;
cout << "2. 按书名查询" << endl;
int type;
cin >> type;
if (type == 1)
{
searchByNo();
}
else if (type == 2)
{
searchByName();
}
else
{
cout << "输入错误,请重新输入" << endl;
searchBook();
}
}
// 修改图书信息
void modifyBook()
{
cout << "请输入要修改的图书编号:" << endl;
int oldNo;
cin >> oldNo;
string query = "SELECT * FROM Books WHERE no = " + to_string(oldNo);
if (mysql_query(conn, query.c_str()) == 0)
{
res = mysql_store_result(conn);
if ((row = mysql_fetch_row(res)))
{
cout << "当前图书信息:" << endl;
cout << "编号\t书名\t作者\t出版社\t价格\t分类" << endl;
cout << row[0] << "\t" << row[1] << "\t" << row[2] << "\t"
<< row[3] << "\t" << row[4] << "\t" << row[5] << endl;
mysql_free_result(res);
// 输入新信息
int newNo = inputNo();
string bookName = inputbookName();
string author = inputAuthor();
string publisher = inputPublisher();
double price = inputPrice();
string category = inputCategory();
query = "UPDATE Books SET no = " + to_string(newNo) +
", bookName = '" + bookName +
"', author = '" + author +
"', publisher = '" + publisher +
"', price = " + to_string(price) +
", category = '" + category +
"' WHERE no = " + to_string(oldNo);
if (mysql_query(conn, query.c_str()) == 0)
{
cout << "修改成功" << endl;
}
else
{
cout << "修改失败: " << mysql_error(conn) << endl;
}
}
else
{
cout << "该编号不存在" << endl;
mysql_free_result(res);
}
}
else
{
cout << "查询失败: " << mysql_error(conn) << endl;
}
}
// 主菜单选择功能
void choose(int input)
{
system("cls");
switch (input)
{
case 1:
cout << "你选择了添加功能" << endl;
add();
break;
case 2:
cout << "你选择了删除功能" << endl;
del();
break;
case 3:
cout << "你选择了修改功能" << endl;
modifyBook();
break;
case 4:
cout << "你选择了列表功能" << endl;
list();
break;
case 5:
cout << "你选择了查询功能" << endl;
searchBook();
break;
case 0:
cout << "退出系统" << endl;
return;
default:
cout << "功能码错误" << endl;
}
system("pause");
system("cls");
}
int main()
{
// 初始化数据库连接
conn = mysql_init(NULL);
// 设置数据库编码为 utf8
mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
// 设置控制台输出编码为 UTF-8
system("chcp 65001");
// 连接数据库
if (!mysql_real_connect(conn, "localhost", "root", "123456", "cppbook", 3306, NULL, 0))
{
cout << "数据库连接失败: " << mysql_error(conn) << endl;
return 1;
}
// 设置连接字符集
mysql_set_character_set(conn, "utf8");
cout << "数据库连接成功!" << endl;
int input = 1;
while (input != 0)
{
cout << "1.添加图书" << endl;
cout << "2.删除图书" << endl;
cout << "3.修改图书" << endl;
cout << "4.图书列表" << endl;
cout << "5.图书查询" << endl;
cout << "0.退出系统" << endl;
cout << "输入选择功能(0-5)" << endl;
cin >> input;
choose(input);
}
// 关闭数据库连接
mysql_close(conn);
return 0;
}
四、运行界面
1.添加界面
2.列表功能
3.修改图书
4.查询图书
5.删除图书
六、总结
通过本次课设,加深了我对《C++程序设计》课程的理论知识的巩固、理解和掌握以及综合应用能力的锻炼。在课程设计期间与老师探讨写代码遇到的问题,也学会了怎么独立的去解决问题,培养了我们查阅资料、独立思考、刻苦钻研和创新的意识。将书本上抽象的概念与具体的实现技术相结合,体会C++语言的设计与实现过程,培养解决问题的实际能力。
通过该设计,理解并掌握了C++面向对象,连接数据库和使用文件流的方法,对C++语言有更深刻的理解,希望以后会在这次基础上完成更多的项目,不断地积累和学习。