news 2026/6/14 3:10:55

图书管理系统(超详细版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
图书管理系统(超详细版)

前端

前端使用的是开源框架,主题的框架主要是由Bootstrap实现

后端

后端采用SpringBoot框架和SpringMVC的三层架构模型

Controller负责前后端的交互,service层负责处理逻辑,Dao层负责处理数据库的交互

  1. 导入所有的依赖(spring和mybatis和mysql和lombok)

Springweb负责提供一个整体的框架,mybatis负责jdbc代码,mysql driver负责进行和数据库的链接,Lombok负责写get和set方法

  1. 配置文件(yml格式)

Applicantion部分是这个项目的名字

Datasource部分是配置和数据库相关的

Mybatis部分是开启驼峰自动转换以及为后续使用动态绑定sql提供路径

Logging部分主要是为了后续使用slf4j框架打印日志

前后端代码实现

用户登录部分

  1. 创建实体类(model)

这里的实体类要求和数据库中的用户表的字段相对应,要求在配置文件中开启驼峰自动转换,加一个@Data,让Lombok帮我们写get and set 和无参的构造方法

三层架构模型(MVC)

Controller

这一层主要就是处理和前端的数据交互然后调用service层

这里主要干的活就是,当前端传入用户的姓名和密码的时候,首先会对传入的信息进行非空校验,为空就返回false,不为空就进行判断,首先会使用service层调用queryByName进行查询如果查不到这个用户就直接返回false,如果查询到了就会进行对比密码,如果密码对的就会设置session,这样就可以让http有记忆,让后端知道后续是谁在进行操作

注意点:

  1. 这里使用equals的时候,要把不为空的常量写在前面,这样就不会报空指针的异常
  2. 这里需要注意我创建了一个常量类来存储session,因为后续使用的地方很多,逐个找去改很麻烦,所以我这里使用常量类去管理

Service层

Service层,这一层就是对逻辑的处理,负责对数据进行处理返回给前端,发送给后端,主要就是调用dao层访问数据库,查询是否有这个用户

Dao层

Dao层,负责和数据库进行交互的,这里的逻辑也很清晰,把上一层传过来的用户名进行查询,如果查不到就返回null

前端

使用jQuery

当用户点击登录按钮的时候,向后端发送ajax请求,并从输入框中取值并发送给后端,等待后端返回值进行判断,成功就跳转到图书页面,错误就弹框提示

成功

错误

展示所有的图书

按照正常的逻辑来说,我只需要一股脑把数据丢给前端,让前端去处理一个页面要留多少个数据

实体类

这个实体类存在的意义就是记录当前在哪一页,一页要展示多少个数据,最核心的是这个offset,这个标志在哪里开始,是用来数据库查询的关键核心

这个是在后端查到的信息,首先是总数,一共在后端查到多少条,每一条的详细消息,这里之所以使用泛型不使用其他的,是因为我返回来的里面有一个list,里面装的是详细的信息,如果我使用list的话就会套娃,就比较麻烦

三层架构

Controller层

这一层的难度就比较大了,让我细细捋一下

因为你要返回给前端的不只是数据,如果发生了错误咋整?是不是需要告诉前端是哪里发生了错误吧,你总不可能直接就返回一个null就让前端去猜吧,那你要被问候了

这里一共分为三个状态,因为这三个状态对应着不同的含义和数据,所以我们可以定义一个枚举类

定义一个Result类

这个类内容包括状态,错误信息,数据

这个类为什么会存在?

这里就是你要返回给前端的详细内容

Success,unlogin,fail

Success状态

成功的话,你就要给前端返回数据和状态对吧,因为返回数据,所以这里需要使用泛型去传递这个数据

Unlogin状态

这里主要就是定义了用户未登录的状态

Fail状态

Fail状态主要是失败,失败之后就要打印这个错误信息

再回到controller层

首先我们在登录界面的时候,就设置了sessionid了,所以这里我们可以根据sessionid去查询这个用户是否存在,只要是不存在或者未登录的都统一返回未登录,只有登录成功之后,才允许把数据传递到service层

Service层

Service的逻辑很简单,因为这里只需要处理一次展示的数据即可,这里需要注意的点是:

  1. 定义一个count表示从后端查询到的总数据的条数
  2. 定义一个list去接收dao层根据要求查到的条数
  3. 最核心的点,数据库存储的时候,状态使用012来表示,要定义一个枚举类,把他转变过来

这个枚举类主要的作用就是把数据库存储的数字按照对应关系变成汉字(枚举类不需要初始化就可以调用,由JVM自动初始化)

Service层进行详细的逻辑处理

Dao层

因为前面我们传入了pagerequest请求,里面包含参数offset和pageSize,表示一次查询多少个,从哪里到哪里

前端

这里的前端使用了jQuery自带的分页插件

使用的时候需要引一下依赖才可以使用

这个是那个分页块的名字,后续在使用翻页的时候需要保持名字一致

这里当打开网页的时候,会执行getbooklist()这个方法,然后执行这个方法的时候,向后端发送ajax请求,在写访问的路径的时候,需要加一个location.search,这个方法的作用就是在url中获取?之后的值,这里你可能会有疑问,这个判断result==null会不会是多余的?一开始我也寻思是多余的,这个存在的意义就是防止极端情况,比如result为null的时候,不用执行result.data这个,否则执行的话,后端会报空指针异常的问题

Jqpageinator这个就好比货架管理员,ajax在后端获取到数据之后,他负责把这些数据放到货架上去

TotalCounts:表示的是元素的总个数

pageSize:表示的是一页有多少个元素

visiblepages:表示一次可视的页数(有多少个按钮)

currentPage:表示当前的页码

onpagechange,当你点击页码的时候时候,Jqpageinator会自动读取到page和type,init是初始化这个页面的时候产生的,只要是初始化非人为点击,就不执行跳转,如果是点击就跳转,同时把page的值赋值给currentpage,这个时候就会getbooklist这个方法,这个时候我们的location.search就发挥作用的,读取?之后的值并赋值个后端对应的参数,注意这里的参数currentPage必须和后端的参数一样,否则后端就没办法返回正确的值

核心注意点:
  1. 导入jqpaginator依赖
  2. 在进入方法的时候需要加上一个location.search,作用是用来获取到后续?之后的参数,方便让后端能返回对应的信息
  3. 在后续使用翻页的时候,记得要加上和后端对应的参数名称
效果

新增图书

Controller层

首先,新增图书本质就是insert数据,,要进行判空处理,要求前端输入的值不能为空,如果为空就返回参数不合法,这个添加图书可能会抛异常,所以需要使用try,catch去捕获异常

Service层

Service层的核心逻辑就是处理添加图书的处理逻辑

Dao层

Dao层负责的是进行和数据库的交互,因为是添加图书,所以这里使用的是insert语句,为什么不用动态sql呢,是因为这里输入的都是必须的信息,所以就不用动态sql

前端

当输入所有的消息的时候,如果一个个去提交就比较麻烦,所以这里提交一个表单的形式比较便捷,当点击提交的时候,发送Ajax请求,如果后端返回空字符串就说明成功,那就可以进行跳转到图书首页,否则就无法跳转弹框提示

效果展示


更新图书

Controller层

这里你可能会有疑问,这里不是更新吗,为什么会出现一个查询的方法,首先,你修改的时候,是不是需要给别人提供修改之前的信息,不给别人提供修改前的信息,别人怎么知道要修改啥

Service层

Service层的逻辑也很简答,service层只需要调用dao层,然后处理一下逻辑即可

Dao层

Dao层的话,因为是更新,所以就是修改,修改的话使用的就是动态的sql,因为并不是每个都修改,推荐使用的是xml的根式,使用set标签和if标签即可

这里需要注意的点就是这个需要配置文件

前端

首先当页面一加载,就会执行Ajax请求,这里加一个location.search的作用就是在url中获取参数,当有数据的时候就会获取出来,由于页面加载的时候url参数可能是其他的,这个ajax不管那么多的,会把url中的全部取出来向后端请求数据,只要后端返回不为空就会继续执行,当我们点击修改的时候,url会变成这样

这个时候ajax就会把这个book.id传到后端接受bookId这个参数的接口中去,这里的bookId必须和后端的bookId一致,这样才能确保你点开的时候,能获取到对应Id的信息

Update

当点击更新的时候,同样会向后端发送一个ajax请求,由于这里的数据太多并且存在于表单之中,所以就可以使用选中这个表单之后序列化把这个数据往后端传输,成功就进行跳转,失败就弹窗提示,整体失败就打印失败的日

效果展示

删除

删除不是真的删除,而是把删除标志置为0,不让他显示出来就行

Controller层

删除的本质就是更新,所以就调用更新的方法

Service层

Dao层

这里使用的也是动态sql进行拼接,如果不想使用就可以使用静态的sql都是可以的,但是由于有现成的我也懒的写多一份

前端

当点击删除的时候,首先会弹框提示是否删除,如果点击确定就会给isDelete赋值为true就会执行后续的Ajax请求,然后向后端发送id和status状态码,进行修改,成功就只需要跳转页面就可

示例图

批量删除

Controller层

批量删除的逻辑是接受前端返回的数据,可能是数组,集合都有可能,这里需要使用参数绑定,因为我接受的是使用集合的方式,这个注解要在url中获取到ids

Service层

Service层接受数据之后进行逻辑处理即可

Dao层

Dao层采用标签foreach进行拼接即可,把ids这个集合里面所有的元素全部取出来,拼接成集合即可

前端

当点击批量删除的时候,就会弹框提示,如果点击确定,那么就会执行if语句,创建一个数组然后把你选中的所有id都放到这个数组之间,然后发送给后端,等后端返回数据进行判断,

数据库

采用Mybatis框架

数据库非常简单,只有两张表,一张是用户表,一张是图书信息表,只需要导入对应的依赖即可

第一个是spring框架mysql driver,后面的是mybatis的驼峰自动转换和动态sql的位置,第三个是日志框架打印详细的日志

用户信息表

图书信息表

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 10:36:14

火灾烟雾早期预警:监控视频中识别异常烟雾形态

火灾烟雾早期预警:监控视频中识别异常烟雾形态 引言:从通用视觉理解到火灾风险的精准捕捉 在智慧城市与公共安全领域,早期火灾预警已成为智能监控系统的核心能力之一。传统的烟雾探测器依赖于物理传感器(如光电、离子式&#xf…

作者头像 李华
网站建设 2026/6/13 15:48:22

万物识别数据闭环:自动收集反馈提升模型

万物识别数据闭环:如何自动收集用户反馈提升模型效果 作为一名AI产品经理,你是否遇到过这样的困境:上线了一个图像识别功能后,用户反馈识别结果不准确,却苦于没有高效的方法收集这些反馈来改进模型?本文将介…

作者头像 李华
网站建设 2026/5/30 21:14:09

计算机视觉竞赛捷径:快速部署基准模型抢占先机

计算机视觉竞赛捷径:快速部署基准模型抢占先机 万物识别-中文-通用领域:开启CV竞赛的“快车道” 在计算机视觉(Computer Vision, CV)竞赛中,时间就是优势。尤其是在比赛初期,快速构建一个可运行的基准模型&…

作者头像 李华
网站建设 2026/6/14 1:24:16

创业三年做到 2kw 营收

我是环界云计算机的创始人,新年又适合发表一下感悟了,其实三年做到 2kw 算速度很慢了,想起去年和 manus 创始人坐一起圆桌,今年人家就几十亿美金被 Meta 收购,感概这个世界变化太快了,人和人之间差距怎么这…

作者头像 李华
网站建设 2026/6/10 12:15:27

优化 .NET 项目中的网格显示

优化 .NET 项目中的网格显示 列跨度可均匀分配空间,使 .NET 网格能够干净利落地适应任何容器宽度,而无需手动调整大小。具有列跨列功能的数据网格可以配置为使列整体延伸以填充容器的整个宽度,从而消除网格边缘的未使用或空白区域。这种行为确…

作者头像 李华
网站建设 2026/6/10 12:47:11

当本科论文第一次被当作“学术起点”而非“毕业门槛”:一个不代写、不越界,却能帮你把课程作业思维升级为初步研究能力的AI协作者长什么样?

对大多数本科生而言,毕业论文是人生中第一次正式接触“研究”二字。但尴尬的是,很多人直到提交前一周,还在纠结:摘要怎么写?文献综述是不是就是摘抄?为什么导师总说“逻辑不顺”?甚至有人自嘲&a…

作者头像 李华