图书管理系统(数据库)

article/2025/11/9 10:02:18

一、项目分析

1、项目功能分析

项目功能模块主要分为三个模块,登录模块、管理员模块、操作员模块。

登录模块包括登录功能,注册功能,登录日志功能,修改密码以及找回密码。

管理员模块包括工作日志功能、图书借阅金额设定、操作员管理功能、图书借阅逾期账单。

操作员模块包括基础信息维护功能,对图书类别、读者类型、罚金进行增删改查的操作,图书信息管理功能是对图书信息的增删改查,读者信息管理功能对读者信息的增删改查,图书借阅管理功能包括图书的借阅,图书的归还以及图书借阅记录的查询。以上就是整个项目的主体功能结构,理清楚需求与结构后,便着手了项目的说明文档。

2、说明文档

说明文档主要从概要设计说明、软件需求说明、接口设计说明、数据库设计说明四个方便对项目的结构,需求,具体的接口,数据库进行全面的规划设计,保证了代码编写的依据性以及合理性。

概要设计说明对项目编写的背景、需求分析、程序运行的流程、功能结构、接口设计、数据库设计以及程序运行出错后的处理方案进行了总体的描述与规划。

软件需求说明是对整个程序进行了具体的需求分析,包括了项目整体的结构图,流程图,ER设计图,为项目的进行和程序的编写提供了方向。

接口设计说明是程序对数据库访问的具体方法的接口设计,接口设计清楚了就能更快速的进行对数据的处理与使用。

数据库设计说明主要是对数据库进行具体的数据表设计,根据软件的具体需求来设计相应的数据表,存放软件产生的数据。

 二、项目实现

 项目编写严格按照了三层架构的标准来设计同时具体体现了简单工厂的设计模式。从Dao类的设计到实体层再到业务逻辑成最后到页面设计,整体的结构清晰明了。然后展示一些代码吧,满满的成就感!

图书借阅Dao:

public interface BookBorrowAndReturnDao {//查询所有借阅记录List<BookBorrowAndReturn> selectAllBorrow(Connection conn);//添加一条借阅记录void addborrow(Connection conn, BookBorrowAndReturn bbr);//修改借阅记录int updateBorrow(Connection conn, int readerId, int ISBN, Date returnDate, BookBorrowAndReturn bbr);//根据readerId查询需要归还的图书记录List<BookBorrowAndReturn> selectBorrowByReaderId(Connection conn, int readerId);//根据isbn和readerId以及状态查询需要归还的图书记录BookBorrowAndReturn selectBorrowByIsbn(Connection conn, int readerId, int isbn, String state);//根据状态和图书编号查询List<BookBorrowAndReturn> selectBorrowByIsbn(Connection connection, int isbn, String state);//根据读者ID和状态查询List<BookBorrowAndReturn> selectBorrowByState(Connection connection, int readerId, String state);
}

图书借阅的Impl:

public class BookBorrowAndReturnImpl extends BaseDao<BookBorrowAndReturn> implements BookBorrowAndReturnDao {//查询所有借阅信息@Overridepublic List<BookBorrowAndReturn> selectAllBorrow(Connection conn) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn";List<BookBorrowAndReturn> beanList = getBeanList(conn, sql);return beanList;}//借书记录@Overridepublic void addborrow(Connection conn, BookBorrowAndReturn bbr) {String sql = "insert into bookborrowandreturn(readerId,readerName,bookISBN,bookName,borrowDate,state) values(?,?,?,?,?,?)";update(conn, sql, bbr.getReaderId(),bbr.getReaderName(), bbr.getISBN(),bbr.getBookName(), bbr.getBorrowDate(), bbr.getState());}@Overridepublic int updateBorrow(Connection conn, int readerId, int ISBN, Date returnDate, BookBorrowAndReturn bbr) {String sql = "update bookborrowandreturn set readerId = ?,readerName = ?,bookISBN = ?, bookName = ?,borrowDate = ? ,returnDate = ?, fine = ? ,state = ? where readerId = ? and bookISBN = ? and returnDate is ?";int update = update(conn, sql, bbr.getReaderId(), bbr.getReaderName(),bbr.getISBN(),bbr.getBookName(), bbr.getBorrowDate(), bbr.getReturnDate(), bbr.getFine(), bbr.getState(), readerId, ISBN,returnDate);return update;}@Overridepublic List<BookBorrowAndReturn> selectBorrowByReaderId(Connection conn, int readerId) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn where readerId = ?";List<BookBorrowAndReturn> beanList = getBeanList(conn, sql, readerId);return beanList;}@Overridepublic BookBorrowAndReturn selectBorrowByIsbn(Connection conn,int readerId, int isbn,String state) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn where bookISbn = ? and state = ? and readerId = ?";BookBorrowAndReturn beanList = getBean(conn, sql, isbn,state,readerId);return beanList;}@Overridepublic List<BookBorrowAndReturn> selectBorrowByIsbn(Connection connection, int isbn, String state) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn where bookISbn = ? and state = ?";List<BookBorrowAndReturn> beanList = getBeanList(connection, sql, isbn,state);return beanList;}@Overridepublic List<BookBorrowAndReturn> selectBorrowByState(Connection connection, int readerId, String state) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn where readerId = ? and state = ?";List<BookBorrowAndReturn> beanList = getBeanList(connection, sql, readerId,state);return beanList;}
}

图书归还功能的部分代码展示:

 页面设计展示:

 程序运行图:

三、项目心得

 利用数据库来实现实现数据的存储比使用文件来储存数据要方便多了也要更快捷了,同时效率也更高了。但是在用的时候出现了一些问题还有在业务逻辑层循环语句的使用上还是避免不了出现错误,多层循环的嵌套容易理不清楚,所以就出现的一些bug进行总结。

1、JDBC使用时sql语句与数据库对应错误。

主要是由于实体层设计时属性名没有与数据表的列名保持一致,从而在sql语句编写出现错误,导致异常,要使用别名来进行联系。

如下图的bookISBN与实体类属性ISBN的不一致:

 public List<BookBorrowAndReturn> selectAllBorrow(Connection conn) {String sql = "select readerId,readerName,bookISBN as ISBN,bookName, borrowDate,returnDate,fine,state from bookborrowandreturn";List<BookBorrowAndReturn> beanList = getBeanList(conn, sql);return beanList;}

 2、多层循环嵌套

在编写图书借阅与归还功能时需要添加许多的限制条件,就难免需要多层循环的嵌套,并且还需要对数据库查询出来的数据存储的集合进行遍历,许多的while循环,for循环,if语句嵌套在一起,当时就出现了循环的多余,以及引用的错误!在进行循环嵌套时首先就要搞清楚每一层循环的作用,并添加注释,那么在出现错误后也能一目了然。

如:

 public void returnBook() {System.out.println("**********************");System.out.println("********图书归还********");System.out.println("**********************");//打印读者信息表System.out.println("读者信息表");new SetReader().selectAllReader();//获取连接Connection conn = null;try {conn = JDBCutils.getConnectionDruid();boolean flag = true;while (flag) {System.out.println("请选择你要进行还书的读者的序号");int Id = TSUtility.readInt();List<Reader> readers = new ReaderDAOImp().selectAllReaders(conn);if (Id > readers.size() || Id <= 0) {System.out.println("选择错误,请重新选择!");} else {flag = false;int readerId = readers.get(Id - 1).getReaderId();//查询选择的序号对应的读者的所有未还记录String state = "未还";BookBorrowAndReturnOperation b = new BookBorrowAndReturnOperation();List<BookBorrowAndReturn> books = b.selectBorrowByState(readerId, state);Date borrowBookDate = null;if (books.size() == 0) {System.out.println("读者" + readers.get(Id - 1).getName() + "暂无未归还记录");} else {System.out.println("====图书未还记录====");System.out.println("序号\t读者ID\t读者姓名\t图书ISBN\t图书名称\t借书日期\t还书日期\t罚金\t状态");for (int i = 0; i < books.size(); i++) {System.out.println((i + 1) + "\t" + books.get(i).getReaderId() + "\t" + books.get(i).getReaderName() + "\t" + books.get(i).getISBN()+ "\t" + books.get(i).getBookName() + "\t" + books.get(i).getBorrowDate() + "\t" + books.get(i).getReturnDate() +"\t" + books.get(i).getFine() + "\t" + books.get(i).getState());borrowBookDate = books.get(i).getBorrowDate();}TSUtility.readReturn();//选择需要归还的图书(一次只能还一本)boolean returnFlag = true;while (returnFlag) {System.out.println("请选择你要还的图书的序号");int bId = TSUtility.readInt();if (bId > books.size() || bId <= 0) {System.out.println("选择错误,请重新选择!");} else {returnFlag = false;int bookId = 0;for (int j = 0; j < books.size(); j++) {bookId = books.get(bId - 1).getISBN();}//设置归还时间Scanner sc = new Scanner(System.in);Date returnDate = null;boolean flagD = true;int days = 0;while (flagD) {System.out.println("请输入归还日期(格式:yyyy-MM-dd):");String date = sc.next();boolean date1 = isDate(date);returnDate = getDateStr(date);if (!date1) {System.out.println("日期格式输入错误,请重新输入");TSUtility.readReturn();} else {//获取借书时间java.sql.Date borrowDate1 = books.get(bId - 1).getBorrowDate();//得到相隔天数int day = daysBetween(borrowDate1, returnDate);//相隔天数//与可借天数对比计算逾期时间double money = 0;Reader reader = new ReaderDAOImp().selectReaderById(conn, readerId);if (day >= 0) {days = day - reader.getLimit();flagD = false;//获取罚金标准根据逾期时间计算罚金String typeName = reader.getTypeName();List<Fine> fines = new FineDaoImpl().selectAllFine(conn);for (Fine fine : fines) {if (typeName.equals(fine.getReaderTypeName())) {//罚金金额if (days <= 0) {System.out.println("您未逾期,感谢您保持良好的信用习惯。");money = 0;} else {money = days * fine.getFine();System.out.println("你已逾期" + days + "天" + ",需缴纳" + money + "元罚金!");}}}String stated = "已还";Date returnDatejiaoyan = null;BookBorrowAndReturn bbr = books.get(bId - 1);bbr.setReturnDate(new java.sql.Date(returnDate.getTime()));bbr.setFine(money);bbr.setState(stated);bbr.setReaderId(readerId);new BookBorrowAndReturnOperation().updateBorrow2(readerId, bookId, (java.sql.Date) returnDatejiaoyan, bbr);System.out.println("归还成功!");//归还成功后需返还读者可借数量Reader reader1 = new ReaderDAOImp().selectReaderById(conn, readerId);int Num = (reader.getMaxBorrowNum() + 1);reader1.setMaxBorrowNum(Num);new ReaderDAOImp().updateReaderById(conn, readerId, reader1);//返还图书库存数Book book = new BookDaoImpl().selectByISBN(conn, bookId);int printTime = (book.getPrintTime() + 1);book.setPrintTime(printTime);new BookDaoImpl().updateBook(conn, book, bookId);} else if (day < 0) {System.out.println("还书日期不能小于借书日期,请重新输入");TSUtility.readReturn();}}}}}}}}} catch (SQLException throwables) {throwables.printStackTrace();} finally {JDBCutils.closeResoureSelect(conn, null, null);}}

最后得到最深的感触是,做项目时一定先把说明文档清清楚楚的做好了,在进行程序的编写,只要有方向的去做,时间会节约,效率会提高,bug一直会存在,但这是最宝贵的经验。未来的日子加油!不负韶华!


http://chatgpt.dhexx.cn/article/2T1n9TsJ.shtml

相关文章

数据库系统设计大作业:图书馆管理系统

数据库系统设计大作业&#xff1a;图书馆管理系统 参考https://blog.csdn.net/dimo__/article/details/84936685中的设计思路&#xff0c;设计了本系统 1 需求分析 针对图书馆的图书管理系统数据库设计&#xff0c;分别对图书馆的读者、一般工作人员和部门负责人进行详细地分…

简单用数据库实现图书管理系统

目录 一、摘要 2、基本功能 二、前言 三、主体 3.1需求分析 3.1.1 数据需求分析 3.1.2 功能需求分析 3.2概要设计 3.2.1 数据字典 3.2.2 ERD&#xff08;实体关系图&#xff09; 3.2.3 DFD数据流图 3.3 逻辑设计 3.3.1 E-R模型向关系模型的转换规则 3.3.2 E-R图转…

MySQL数据库期末项目 图书馆管理系统

1 项目需求分析 1.1 项目名称 图书馆管理系统 1.2 项目功能 在以前大多部分图书馆都是由人工直接管理&#xff0c;其中每天的业务和操作流程非常繁琐复杂&#xff0c;纸质版的登记信息耗费了大量的人力物力。因此图书馆管理系统应运而生&#xff0c;该系统采用智能化设计&#…

tar文件是什么?怎么解压?

例如在使用coco数据集的时候&#xff0c;下载下来是这样的两个文件&#xff1a; 恕我无知&#xff0c;之前完全没见过这种格式的文件。 经过一番咨询&#xff0c;原来是一种压缩文件&#xff0c;里面藏了很多内容&#xff0c;看它的大小就能猜到。 这种文件一般的压缩软件貌似…

常用的tar解压命令总结

&#xff8d;^ヽ&#xff64;  /⌒&#xff64;  ,   |  &#xffe3;7  (⌒r⌒7/   レ   &#xff3c;/&#xffe3;&#xff3c;&#xff63; &#xff3f;/         { _&#xff8c; ●       ゝ _人   ο  ●  ナ   ト&#xff64;&…

linux中.tar文件怎么解压

linux中.tar文件怎么解压 1、打包压缩tar -cvf etc.tar /app/etc #打包 tar -zcvf pack.tar.gz pack/ #打包压缩为一个.gz格式的压缩包 tar -jcvf pack.tar.bz2 pack/ #打包压缩为一个.bz2格式的压缩包 tar -Jcvf pack.tar.xz pack/ #打包压缩为一个.xz格式的压缩包 2、解…

Linux 解压tar

Linux系统中tar压缩包怎么解压&#xff1f;Linux系统中有一个tar压缩包格式的文件需要解压&#xff0c;但是linux系统中没有找到tar的命令&#xff0c;该怎么办呢&#xff1f;下面我们就来看看详细的教程&#xff0c;需要的朋友可以参考下 在Linux的默认的版本中不是所有的命令…

解压缩命令tar zip rar

文章目录 打包和压缩的概念tar常用独立命令打包压缩查阅tar包内有哪些文件解压缩到指定目录(默认是当前目录)只将tar内的部分文件解压出来其他命令(其他) zip和unziprar和unrar 打包和压缩的概念 tar命令可以为linux的文件和目录创建档案 利用tar&#xff0c;可以为某一特定文件…

【hardware】什么是H桥电路?

前言 初玩智能车的小伙伴肯定会涉及到驱动电机正反转的时候&#xff0c;那么该如何控制智能车呢&#xff1f;这就要讲到双H桥了&#xff0c;让我来给你们分析吧&#xff01; 1.三极管 讲到双H桥&#xff0c;那么首先得介绍两种三极管&#xff0c;S8550&#xff08;PNP型&#x…

关于H桥的理解和应用

很多用电器对电源极性要求不高&#xff0c;如点灯&#xff0c;正反接都可以工作&#xff0c;而且现象都差不多&#xff0c;也有的用电器对电源极性敏感&#xff0c;而且接反了就不工作&#xff0c;例如多数半导体器件&#xff0c;LED等&#xff1b;但也有的用电器对电源极性敏感…

H桥驱动电路原理【转】

H桥驱动电路原理 一、H桥驱动电路 图4.12中所示为一个典型的直流电机控制电路。电路得名于“H桥驱动电路”是因为它的形状酷似字母H。4个三极管组成H的4条垂直腿&#xff0c;而电机就是H中的横杠&#xff08;注意&#xff1a;图4.12及随后的两个图都只是示意图&#xff0c;而…

STM32F1基于H桥的电机控制程序分析

这里写自定义目录标题 N-MOS H桥结构控制原理MOS驱动调速的实现控制程序编写 N-MOS H桥结构 控制原理 N-MOS的G极与S级的电压差大于某一值的时候&#xff0c;D极和S极之间导通&#xff0c;DS电阻极小&#xff0c;可看作导线&#xff0c;否则DS之间视为断路。 因此有以下控制方…

一份很用心的H桥驱动扫盲教程

什么是H桥&#xff1f; H桥是一个比较简单的电路&#xff0c;通常它会包含四个独立控制的开关元器件&#xff08;例如MOS-FET&#xff09;,它们通常用于驱动电流较大的负载&#xff0c;比如电机&#xff0c;至于为什么要叫H桥&#xff08;H-Bridge&#xff09;&#xff0c;因为…

电机控制-H 桥电路 控制方式简单解析

声明&#xff1a;本片文章来自互联网&#xff0c;侵删 电机控制-H 桥电路 控制方式简单解析 什么是H桥一. 开关状态1.1、正转1.2、反转1.3、调速 二. 停止状态2.1 第一种停止方式2.1 第二种停止方式 什么是H桥 H桥是一个比较简单的电路&#xff0c;通常它会包含四个独立控制的…

PWM驱动MOS管H桥电路

H桥是一个典型的直流电机控制电路&#xff0c;因为它的电路形状酷似字母H&#xff0c;故得名与“H桥”。4个三极管组成H的4条垂直腿&#xff0c;而电机就是H中的横杠&#xff08;注意&#xff1a;图中只是简略示意图&#xff0c;而不是完整的电路图&#xff0c;其中三极管的驱动…

基于STM32的电机--直流有刷电机H桥驱动的不同模式分析

文章目录 直流电机驱动设计1.电机驱动硬件配置2.电机驱动电路分析简单正向电路最简单的电机正反转电路H桥电路分析受限单极模式单极模式双极模式 减速电机的重要参数 直流电机驱动设计 1.电机驱动硬件配置 直流电机旋转&#xff1a;给电机提供两根线&#xff0c;以提供电压正…

深入浅出H桥驱动电路

什么是H桥? H桥是一个比较简单的电路,通常它会包含四个独立控制的开关元器件(例如MOS-FET),它们通常用于驱动电流较大的负载,比如电机,至于为什么要叫H桥(H-Bridge),因为长得比较像字母H,具体如下图所示; 这里有四个开关元器件Q1,Q2,Q3,Q4,另外还有一个直流电机…

mos管h桥电机驱动电路与设计原理图-KIA MOS管 (kiaic.com)

来源&#xff1a; mos管h桥电机驱动电路与设计原理图-KIA MOS管 (kiaic.com) 一、mos管H桥电路 图1中所示为一个典型的直流电机控制电路。 电路得名于“H桥驱动电路”是由于它的外形酷似字母H。4个三极管组成H的4条垂直腿&#xff0c;而电机就是H中的横杠&#xff08;留意&…

【开源电机驱动】H 桥驱动-硬件篇

原文地址&#xff1a;http://www.modularcircuits.com/blog/articles/h-bridge-secrets/h-bridge_drivers/ 本文翻译校正稿件&#xff0c;含有译者批注 H-Bridge Drivers H 桥驱动-硬件篇 Introduction 引言 In the previous installment of the series we’ve gone through…

【大电流H桥电机驱动电路的设计与解析(包括自举电路的讲解,以IR2104+LR7843为例)】

一.简介 之前介绍过H桥电机驱动电路的基本原理&#xff0c;但是以集成的电机驱动芯片为示例。这些集成的芯片使用起来比较简单&#xff0c;但是只能适用于一些小电流电机&#xff0c;对于大电流的电机(比如&#xff1a;RS380和RS540电机&#xff09;&#xff0c;则不能使用这些…