图书管理系统总体设计报告
图书管理系统概述
本次项目设计并实现了一个精简的多用户图书管路系统。应用后端通过与 MySQL 进行连接实现对数据的管理。用户可以通过界面实现登陆、注册、借书、还书等操作。管理员可以通过登陆界面实现对用户和书籍的管理,具有添加/删除用户/书籍等权限。界面输入的数据由后端连接 MySQL 储存在本地。
一、整体功能描述
用户类型及权限:
游客: 只能查询和检索相应的书籍信息。不能借阅书籍。
用户: 能够查询相应的书籍信息。需要在登陆后才能借阅归还书籍。
管理员:可以查询相应书籍信息。在登录后拥有对书籍和用户的管理权限。
能够向数据库插入、删除书籍。更新相应书籍信息。
能够查询用户信息,添加或删除用户。查询用户借书情况等。
插入书籍既可以单本入库,也可以通过脚本文件批量入库。
图片 1 用户类型及其操作
查询操作:
书籍的查询操作实现了条件检索的功能,即可以通过输入书籍的部分或全部信息或关键词检索出全部符合要求的书籍。
登录操作:
登录时直接根据用户输入的 ID 辨别用户类型(普通用户或者管理员),通过匹配数据库的信息确定用户是否存在、密码是否正确等。
书籍借阅/归还:
用户登录后拥有借阅或归还书籍的权限。通过选中查询列表中的书籍可以进行书籍借阅操作(只能借阅有余量的书籍)。用户可以在自己借阅书籍列表中选中相应书籍归还。
用户管理:
管理员登录后会出现用户管理的界面。可以输入用户信息添加新用户,也可以输入用户 ID 查询用户详细信息或者从用户列表中选中用户进行删除等。删除用户时管理员只能删除没有借阅书籍的用户。
书籍管理:
管理员具有书籍管理的权限。管理员可以插入新的书籍或者对已有的书籍信息进行更新。插入书籍有单个书籍插入和脚本文件批量插入两种模式。通过输入相应书籍信息进行书籍插入操作。其中必要的信息不能为空。
在插入书籍时,如果相应书籍信息已经存在,即书籍 ID 已经存在,则更新相应书籍,并将书籍的库存量增加到已有书籍上。如果书籍不存在,则直接添加书籍。
删除书籍时,同样添加了条件检索功能。管理员可以通过输入条件检索出所有所要删除的书籍的信息。在删除列表中选中相应书籍就能实现删除操作。删除书籍时管理员只能删除没有被用户借阅过的书籍。
二、运行环境和配置
开发平台:Windows
开发工具:Visual Studio 2015 /Qt Creater / MySQL 开发语言:C++
三、参考资料
C++ GUI programming with Qt4
C++ Primer 中文版 第 5 版 电子工业出版社
四、图书管理系统设计
图书管理系统架构
图书管理系统主要定理了三个类来处理相应操作:library 类与 controller 类与 log_ctl 类。
其中 library 类实现了对界面的管理维护更新,处理用户输入数据等功能。
Controller 类则用来实现与 MySQL 进行交互,更新数据库信息等功能。Log_ctl 类主要用来初始化数据库设置,实现程序与数据库的连接。模块之间相应关系如下图所示。
图片 2 系统架构层次
数据类型定义
为便于前后端交互定义相应的数据类型:
class User { public:
string id; string name; string password; class Book { public:
std::string book_id; std::string name; std::string author;
bool priv;
int booknum;
};
class UserQuery { public:
string id; string name; string password;
std::vector<User> Users;
};
class Manager { public:
string id; string name;
string password;
};
double price;
int num; //书的总量
int stock;
std::string publisher; std::string publish_date; std::string type;
};
class BookQuery { public:
std::string book_id; std::string name; std::string author; std::string type; int begin_year; int end_year; std::string publisher; double low_price; double high_price; bool have_stock;
std::vector<Book> Catalog;
};
class Borrow { public:
std::string book_id; std::string user_id; std::string borrow_date;
std::string return_date;
};
其中 Book 类储存单本书籍信息。
BookQuery 类用于查找书籍操作。找到的书籍信息返回到 vector中,如果 vector为空,则代表没有找到相应书籍。
Borrow 类用来储存数据库中的 borrow 表中的信息。
User 类用来储存单个用户的信息。
UserQuery 用来查找相应用户,符合要求的用户放在 vector,如果 vector为空,则代表没有找到。
Manager 类用来储存管理员信息。
后端设计实现
后端各模块功能说明
登录注销模块
功能说明:本模块主要负责系统的登录和注销功能,与前端的登录和退出功能对应。
控制器模块
功能说明:后端的核心模块,负责书籍、用户、管理员的全部操作。书籍信息的查询、插入、删除、借出归还情况查询,用户的借书、还书、以及相关信息的查询,管理员的增删书籍、用户的增删操作、用户的查询操作。
后端各模块定义及接口说明
登录注销模块
class log_ctl {
public:
log_ctl(string host, string username, string password, string db);
bool log(MYSQL& sql);
void exit_ctl(MYSQL& sql);
private:
string host;
string username;
string password;
string db;
};
接口说明:
定义登录控制器类模块,提供登录、注销函数:
log_ctl(string host, string username, string password, string db)
参数说明:
string host 主机域名 string username 用户名 string password 登录密码 string db :数据库名返回值:构造函数无返回值 bool log(MYSQL& sql)
参数说明:
MYSQL& SQL 数据库连接句柄
**返回值:**返回登录状态
void exit_ctl(MYSQL& sql)
参数说明:
MYSQL& SQL 数据库连接句柄返回值:无 2、 控制器模块
class controller {
private:
string interpret(BookQuery & q);
int type;
public:
void select(BookQuery & q, MYSQL& sql);
int insert(Book& q, MYSQL& sql);
bool insertuser(User & _user, MYSQL &sql);
bool selectUser(User &_user, MYSQL &sql);
bool selectManager(Manager &_manager, MYSQL &sql);
bool displayUser(UserQuery &q, MYSQL &sql);
void displayborrow(string user_id, BookQuery &q, MYSQL& sql);
int borrowbook(string user_id, string book_id, MYSQL &sql);
int returnbook(string & user_id,string & book_id, MYSQL &sql);
bool deleteuser(User & _user, MYSQL &sql);
bool deletebook(string& book_id, MYSQL& sql);
bool SelectBorrow(Borrow& q, MYSQL& sql);
void AddFile(string& info, vector<Book>& book, MYSQL& sql);
}
接口说明:
string interpret(BookQuery & q);
参数说明:
BookQuery & q 查询信息类
返回值:返回处理后的查询语句函数功能:将查询需求处理成对应语句,以 string 类的形式返回,本函数作为类内私有函数。
void select(BookQuery & q, MYSQL& sql);
参数说明:
BookQuery & q 查询信息类
MYSQL& SQL 数据库连接句柄返回值:无函数功能:对需求的查询信息 q 进行查询,将查询结果写到 BookQuery 类内的 Book 数组中。
int insert(Book& q, MYSQL& sql);
参数说明:
Book& q 插入的数据信息
MYSQL& SQL 数据库连接句柄
返回值:插入状态函数功能:对需要插入的书籍信息插入到所给句柄数据库中,插入成功返回 1,插入失败返回 0
bool insertuser(User & _user, MYSQL &sql);
参数说明:
User & _user 插入的用户信息
MYSQL& SQL 数据库连接句柄
返回值:插入状态函数功能:对需要插入的用户信息插入到所给句柄数据库中,插入成功返回 1,插入失败返回 0
bool selectUser(User &_user, MYSQL &sql);
参数说明:
User & _user 用户的查询信息
MYSQL& SQL 数据库连接句柄
返回值:查询状态函数功能:条件查询用户信息,查询条件在_user 中给出,查询结果写入到_user 类中的 user 数组中。查询成功返回 1,查询失败返回 0。 bool selectManager(Manager &_manager, MySQL &sql);
参数说明:
Manager &_manager 管理员的查询信息
MYSQL& SQL 数据库连接句柄
返回值:查询状态函数功能:查询管理员信息,查询条件在_manager 中给出,查询结果写入到
_manager 类中的 manager 数组中。查询成功返回 1,查询失败返回 0。
bool displayUser(UserQuery &q, MYSQL &sql);
参数说明:
UserQuery &q 用户操作类
MYSQL& SQL 数据库连接句柄
返回值:查询状态函数功能:无条件查询用户信息,查询结果写入到_manager 类中的 manager 数组中。查询成功返回 1,查询失败返回 0。
void displayborrow(string user_id, BookQuery &q, MYSQL& sql);
参数说明:
string user_id 用户 id
MYSQL& SQL 数据库连接句柄
返回值:查询状态函数功能:根据用户 id 查询用户借书信息,查询结果写入到 q 中的 book 数组中。查询结果若为空则将 Book 数组清空。
int borrowbook(string user_id, string book_id, MYSQL &sql);
参数说明:
string user_id 用户 id
MYSQL& SQL 数据库连接句柄
返回值:查询状态函数功能:为用户 id 为 user_id 的用户借一本书,若借书成功返回 1,借书失败返回 0。
int returnbook(string & user_id,string & book_id, MYSQL &sql);
参数说明:
string user_id 用户 id string & book_id 书籍 id
MYSQL& SQL 数据库连接句柄
返回值:还书状态函数功能:为用户 id 为 user_id 的用户还一本本书,书的 id 为 book_id。若还书成功返回 1,还书失败返回 0。
bool deleteuser(User & _user, MYSQL &sql);
参数说明:
User & _user 用户信息
MYSQL& SQL 数据库连接句柄
返回值:删除状态函数功能:删除数据库中的一个用户,用户信息储存在_user 中。若删除成功则返回 1,删除失败返回 0。
bool deletebook(string& book_id, MYSQL& sql);
参数说明:
string& book_id 书籍 id
MYSQL& SQL 数据库连接句柄
返回值:删除状态函数功能:删除数据库中的一本书,书的 id 为 book_id。若删除成功则返回 1,删除失败返回 0
bool SelectBorrow(Borrow& q, MYSQL& sql);
参数说明:
Borrow& q 借书查询
MYSQL& SQL 数据库连接句柄
返回值:查询状态
函数功能:查询借书情况,详细的查询信息储存在 Borrow& q 中。若查询成功则返回 1,查询失败返回 0.
void AddFile(string& info, vector<Book>& book, MYSQL& sql);参数说明:
string& info 文本文件中的信息
vector<Book>& book 输出的结果返回值
- MYSQL& SQL 数据库连接句柄
- 返回值:无
- 函数功能:批量处理文本文件中的信息,将书籍信息储存到 book 向量中。无返回值。
4.4 前端设计实现
对界面的操作和处理过程以及和后端的交互操作主要在 Library 类里实现。
一个 library 对象就是一个界面对象。通过对 library 类的实例化来产生用户交互界面。同时在 library 类中定义相应的变量及函数调用 controler 及 log_ctl 实现图书管理系统。
Library 类主要成员变量
class Library : public QObject
{
Q_OBJECT
public:
Library(QObject* parent = 0);
~Library();
/*
三种权限:
0 manager 可以查询借书还书,入库出库
1 user 可以查询,借书还书
2 visitor 可以查询
*/ private:
enum { MANAGER, USER, VISITOR};
QString userName;
QString userID; QString userPassword;
int user_type;//人员的类型: user, visitor, manager MYSQL sql; controller Control;
QWidget *WholeWindow;
QVBoxLayout* VlayoutWhole;
QTabWidget* WholeTabwidget;
……
} //下方的工作区
其中 QString 变量 userName,userID,userPassword 用来记录用户的名字,ID 和登陆密码。用户名初始化为 ”游客”。
其中对象 MySQL SQL 是用来调用 MySQL 的成员对象,controler Control 是用来操作调用相应后端函数的控制台对象。
QWidget* WholeWindow 即为显示整个界面的窗口对象指针,整个工程的实现即通过对 WholeWindow 的实例化。
系统主要通过用户对界面的操作(如点击按钮,输入文本信息等)来调用 library 中相应的函数实现功能。
其中 library 类通过读取用户在文本框中的信息,储存到相应的类中(如 Book 类,User 类等)。通过将这些类传递给 controler 的函数,调用 MySQL 的查询函数,获取数据库中相应的数据,随后用这些数据调用 library 中的函数实现对界面的更新操作。
Library 中主要成员函数
private:
void LayoutWindow(); void SetTitle(); void SetMainWidget();
/*设置不同的窗口格式*/
void setwindow1(); //查询窗口,图书搜索 void setwindow2(); //用户借阅情况 void setwindow3(); //用户管理 void setwindow6(); //书籍管理 void setwindow7(); //单册入库 void setwindow8(); //多册入库 void setwindow9(); //删除书籍
private:
bool Isselectall01(); //判断表格 Table01 中的勾选框是否被全选
bool Isselectall2(); //判断表格 Table2 中的勾选框是否被全选 void Island(bool);
void Longon_inChangeWindow1();
void Longon_outChangeWindow1(); void ShowBook2(BookQuery&); void ShowUser3(UserQuery&); void ShowUser4(string); void Query9(BookQuery&);
void ShowBook8(vector<Book>&);
private slots://信号槽
void updatetime();
void setwindow4(); //点开用户详细信息触发窗口 void setwindow5(); //添加新用户触发窗口 void setwindow01(); //查看要删除的书籍 void setwindow02(); //用户登录 void setbutton011();//全选表格 Table01 中的勾选框 void setbutton21(); //全选表格 Table2 中的勾选框 void setbutton72(); //清空输入的信息 void setbutton83(); //清空输入的信息 void setbutton92(); //清空输入信息
void Query1(); //窗口 1 中的查询
void QueryTree1(QTreeWidgetItem*, int); //窗口 1 点击 QTreeWidget void AddBook7(); //窗口 7 添加书籍 void AddUser5(); //窗口 5 添加用户 void Logon(); //登录 void Logon_out(); //注销 void Borrow_Book(); //借阅选中的书 void Return_Book(); //归还选中的书
void DeleteUser3(); //删除选中的用户
void OpenFile(); void DeleteBook01();
void AddBook8();
};
注:因为类中调用成员函数过多,不在报告中一一说明,具体实现可以查看源代码。
五、工程实现效果
开始界面
若界面登陆成功并成功连接 MySQL,则跳出提示框。
书籍检索
书籍检索实现条件检索的功能。可以在上面搜索框中输入相应信息检索符合条件的书籍。点击开始检索按钮就可以进行检索。通过勾选框勾选只有余量的书籍,则只检索有余量的书籍。若不输入任何信息,直接点击借阅书籍按钮,则列表中会列出数据库中所有书籍的信息。
因为没有登录,则当前用户显示为游客。“游客”只具有查询书籍的权限不具备其他权限。
用户登录
点击登录按钮则进入登录界面,只需要输入用户 ID 和密码即可。
若输入信息错误则会有相应提示等。
用户登录成功以后发现当前用户名改为登录人的用户名。并且书籍列表中增加勾选框,书籍列表下方增加借阅书籍按钮。栏目里多出借阅情况标题栏。
勾选相应书籍,点击借阅书籍按钮即可借阅书籍。到借阅情况窗口中便可查看用户借阅书籍的情况。
观察借阅情况窗口:
书籍的默认借阅天数为 30 天。并显示出借阅日期和归还日期。选中书籍后点击归还书籍即可归还相应书籍。
点击注销按钮则注销为游客身份。不能再借阅书籍。
管理员登录
采用管理员账号登陆后发现新出现两个窗口:用户管理和书籍管理。当前用户名更新为管理员用户名。
用户管理
用户管理窗口则会列出当前所有的用户列表和其借阅书籍的数目。在右侧窗口中可以输入用户 ID 来查询用户的详细信息。
在用户的详细信息里会列出用户的名字,ID,密码,借书权限及借书数目等。
并且在书籍列表中会列出用户借阅的所有书籍及借阅归还日期等。
点击右侧添加用户便可添加新用户。
发现用户添加成功。
勾选相应勾选框,点击删除用户按钮则可删除选中用户。
根据系统特性,只能删除没有借书记录的用户。
若用户删除成功,则弹出提示框。
书籍管理
书籍管理窗口分为三个子窗口,分别为单册添加书籍,通过脚本批量导入书籍和删除书籍。
添加单册书籍:单册添加书籍通过输入书籍信息即可成功添加。
添加书籍后,在书籍检索窗口中发现发现书籍已经成功导入数据库。
批量导入书籍:导入的脚本文件为:
导入后效果:
点击确认添加即可完成书籍添加:
发现数据库中书籍已更新。
删除书籍:删除书籍操作同样支持条件查找。
查询结果为:
勾选相应的书籍点击删除按钮即可完成删除操作。删除时只能删除没有借出的书籍。
MySQL 中的相应表数据类型
create table manager
(
id varchar(20) primary key, name varchar(20),
password varchar(20)
);
create table user( id varchar(20) primary key, name varchar(20),
password varchar(20)
);
create table book( book_id varchar(20) primary key, name varchar(20) not null, author_name varchar(20), price numeric(9,2), num int not null, stock int not null,
publisher varchar(20), publish_year year, type varchar(20) not null, check (num > 0),
check (book_id != '')
);
create table borrow( user_id varchar(20), book_id varchar(20), borrow_date date, return_date date,
primary key(user_id,book_id), foreign key (user_id) references user(id), foreign key (book_id) references book(book_id)
);