SpringBoot项目----图书管理系统(详解)

news2024/9/23 11:19:10

目录

项目业务

 技术栈

数据库表的设计 

数据库表关系图

关于字典表 

前后端接口实现

1.初始化数据库、表、数据

2.数据库连接池配置

3.统一响应封装

 4.统一异常处理

5.实现统一会话管理(登录) 

5.通过Mybatis生成工具,生成mapper接口,xml文件,实体类

 6.准备所有的Controller和servise类

7.实现接口

(1)登录接口

(2)实现注销接口

 (3)实现数据字典下拉菜单

(4)获取班级信息

(5)获取学生信息

(6)班级管理页面-表格展示

说明 

(7)新增接口

(8)获取数据详情(每一条) 

(9)修改接口

(10) 删除接口

 总结


项目业务

使用者:图书馆管理员

业务:管理学校图书信息,记录并管理学生借阅图书信息

有以下几个模块 

 

 技术栈

  • SpringBoot
  • SpringMVC
  • MyBatis

数据库表的设计 

数据库表关系图

关于字典表 

数据字典表和数据字典标签表主要用在一些通用的下拉菜单选项。
像本项目在班级表中的专业和毕业年份

如果单独设计需要单独一张表,实际存放的数据也不会太多,可以考虑设计在整体的一张表中。

一般在设计上考虑为两张表:数据字典表和数据字典标签表(一对多关系)来保存。两张表都是 key、 value 的形式,字典表是父节点对应下拉菜单,字典标签表是子节点对应下拉菜单选项,下拉菜单通过父节点的 key 查询出所 有关联的子节点,再使用子节点的key、 value 进行下拉菜单选项的初始化。

 

前后端接口实现

我这里只给大家说后端接口的实现,前端大家可以在github上找

  • 需要说明的是,接口的定义一般是前后端约定好的,所以也和前端代码息息相关,前端需要什么数据, 需要什么格式的数据,也会在接口中体现。

1.初始化数据库、表、数据

这里大家就创建以上那几个表,然后插入一些数据,在自己的MySQL执行一下

2.数据库连接池配置

在pom.xml插入以下代码,并替换成自己的用户名和密码

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=***
spring.datasource.password=*******

3.统一响应封装

一次http请求,调用Controller请求映射方法(返回值Object)

正常返回:ResponseResult(success=true,data=obj)

出现异常:ResponseResult(success=false,message=错误信息)

 4.统一异常处理

若程序内部错误:如语法错误、SQL写错,这种错是一大段英文,不能给用户看,这里设置返回中文的json字符串

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handleException(Exception e){
        log.error("系统出错啦", e);
        ResponseResult json = new ResponseResult();
        json.setMessage("系统出错了,请联系管理员");
        return json;
    }

还有一种是返回自定义异常:如用户名不存在、密码错误……

   @ExceptionHandler(AppException.class)
    @ResponseBody
    public Object handleAppException(AppException e){
        log.debug("自定义异常", e);
        ResponseResult json = new ResponseResult();
        json.setMessage(e.getMessage());
        return json;
    }

5.实现统一会话管理(登录) 

这里是用springMVC的HandlerInterceptor拦截器实现的,登录成功可以访问,未登录重定向到登录界面

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断是否登录
        HttpSession session = request.getSession(false);
        if(session != null){//获取登录时保存的用户信息
            User user = (User) session.getAttribute("user");
            if(user != null){//登录,允许访问
                return true;
            }
        }
        //未登陆,不允许访问
        String servletPath = request.getServletPath();//服务路径
        if(servletPath.startsWith("/api/")){//后端接口,未登陆返回401,json
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.setStatus(401);
            ResponseResult json = new ResponseResult();
            json.setMessage("未登陆,不允许访问");
            response.getWriter().println(objectMapper.writeValueAsString(json));
        }else{//前端页面,未登陆,重定向到登录页面
            String schema = request.getScheme();// http
            String host = request.getServerName();//服务端ip或域名
            int port = request.getServerPort();//port
            String contextPath = request.getContextPath();//应用上下文路径
            String basePath = schema+"://"+host+":"+port+contextPath;
            response.sendRedirect(basePath+"/index.html");
        }
        return false;
    }

添加要拦截的前端页面,和所有后端接口,除了注册、登录

registry.addInterceptor(new LoginInterceptor(objectMapper))
                //前端:添加要拦截的页面
                .addPathPatterns("/page/main.html")
                //拦截所有后端接口,排除用户注册,登录
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/user/login")
                .excludePathPatterns("/api/user/register");

5.通过Mybatis生成工具,生成mapper接口,xml文件,实体类

 6.准备所有的Controller和servise类

每个实体类对应一个Controller和一个Service

例:

@RestController  //注册到容器中
@RequestMapping("/book")  //设置路径
public class BookController {
    @Autowired  //注入
    private BookService bookService;
@Service
public class BookService {
    @Autowired
    private BookMapper bookMapper;

7.实现接口

(1)登录接口

点击登录抓包可得:

可见请求路径为:POST http://localhost:8080/api/user/login

在UserController中写登录接口

//POST http://localhost:8080/api/user/login
    @RequestMapping("/login")
    public Object login(@RequestBody User user, HttpServletRequest request){
        //  1.根据账号查询数据
        User param=new User();
        param.setUsername(user.getUsername());
        User exist=userService.selectOne(param);
//        未查询到用户
        if(exist==null){
            throw new AppException("账号不存在");
        }
//        2.若查询到用户校验密码是否正确
        if(!exist.getPassword().equals(user.getPassword())){
            throw new AppException("账号或密码错误");
        }
//        3.验证成功,创建session,保存用户信息
        HttpSession session=request.getSession();
//        保存用户信息,和拦截器的键一致
        session.setAttribute("user",exist);
        return null;
    }

然后生成selectOne方法,并返回 userMapper.selectOne();

 

public User selectOne(User param) {
        return userMapper.selectOne(param);
    }

(2)实现注销接口

登录后会创建JSESSIONID及session,返回JSESSIONID(set-Cookie:JSEESION=xxx)

每次请求会自动携带Cookie:JSESSIONID=xxx

实现注销功能只用删除session即可

//    GET http://localhost:8080/api/user/logout
    @RequestMapping("/logout")
    public Object logout(HttpSession session){
        session.invalidate();
        return null;
    }

 (3)实现数据字典下拉菜单

//    实现数据字典接口: 获取下拉菜单的选项
//    GET dict/tag/query?dictionaryKey=000002
    @RequestMapping("query")
    public Object query(String dictionaryKey){
        List<DictionaryTag> tags=dictionaryTagService.query(dictionaryKey);
        return tags;
    }
   public List<DictionaryTag> query(String dictionaryKey) {
        return dictionaryTagMapper.queryTagsByKey(dictionaryKey);
    }

Mybatis生成工具并未生成这个queryTagsByKey方法,需要自己写(关联查询)

  <select id="queryTagsByKey" resultMap="BaseResultMap">
    select
      concat(d.dictionary_key,dt.dictionary_tag_key) dictionary_tag_key,
      dt.dictionary_tag_value
    from
      dictionary d, dictionary_tag dt
    where
      d.id=dt.dictionary_id
    and
      d.dictionary_key=#{dictionaryKey}
  </select>

(4)获取班级信息

//    获取班级(下拉菜单选项)信息接口
//    GET http://localhost:8080/api/classes/queryAsDict
    @RequestMapping("/queryAsDict")
    public Object queryAsDict(){
        List<Classes> classes=classesService.queryAsDict();
        return classes;
    }

(5)获取学生信息

//    获取学生信息(下拉菜单)
//    GET student/queryAsDict?dictionaryKey=2
    @RequestMapping("/queryAsDict")
    public Object queryAsDict(@RequestParam("dictionaryKey") String classesId){
        List<Student> students=studentService.queryAsDict(classesId);
        return students;
    }

(6)班级管理页面-表格展示

//    获取班级信息(表格展示)
//    GET /api/classes/query
    @RequestMapping("/query")
    public Object query(Classes cla){
//        分页功能
        PageHelper.startPage(cla);
        List<Classes> classes=classesService.query();
        PageHelper.clearPage();
        return classes;
    }

说明 

每个页面都有5个接口 :

  • 获取数据(表格展示)
  • 新增
  • 修改删除
  • 获取数据详情

 

我这里以班级管理为例,实现的方法都是一样的(否则博客太长了,分两篇的话,第二篇内容又不多)

(7)新增接口

//    新增班级
//    POST /api/classes/add
    @RequestMapping("/add")
    public Object add(@RequestBody Classes classes){
        int n=classesService.add(classes);
        return null;
    }
    public int add(Classes classes) {
        return classesMapper.insertSelective(classes);
    }

(8)获取数据详情(每一条) 

//    获取班级详情
//    GET http://localhost:8080/api/classes/queryById?id=4
    @RequestMapping("/queryById")
    public Object queryById(@RequestParam Integer id){
        Classes classes=classesService.queryById(id);
        return classes;
    }
    public Classes queryById(Integer id) {
        return classesMapper.selectByPrimaryKey(id);
    }

(9)修改接口

//    修改信息
//    POST http://localhost:8080/api/classes/update HTTP/1.1
//    抓包
//    {"id":"4","classesName":"二年级(1)班","classesGraduateYear":"000001004","classesMajor":"000002001","classesDesc":"无"}
    @RequestMapping("/update")
    public Object update(@RequestBody Classes classes){
        int n=classesService.update(classes);
        return null;
    }

接收json格式的数据 加@RequestBody注解---(抓包看接收啥数据格式)

(10) 删除接口

//    删除数据
//    GET http://localhost:8080/api/classes/delete?ids=2&ids=3
    @RequestMapping("/delete")
    public Object delete(@RequestParam List<Integer> ids){
        int n=classesService.delete(ids);
        return null;
    }
  public int delete(List<Integer> ids) {
        return classesMapper.deleteByIds(ids);
    }

 总结

项目到这里就结束了,其他四个页面大家可参考班级管理的代码实现,此外,还可以实现分页功能,搜索功能,忘记密码等等。如果大家想让自己的项目变得丰富起来的话,可以在网上找资料自己实现这些功能。

 

 也可以来问我哦~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/510761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据之Hadoop】二十九、HDFS存储优化

纠删码和异构存储测试需要5台虚拟机。准备另外一套5台服务器集群。 环境准备&#xff1a; &#xff08;1&#xff09;克隆hadoop105为hadoop106&#xff0c;修改ip地址和hostname&#xff0c;然后重启。 vim /etc/sysconfig/network-scripts/ifcfg-ens33 vim /etc/hostname r…

JVET-AD0081:一种基于外推滤波器的帧内预测模式

本提案提出了一种基于外推滤波器的帧内预测&#xff08;extrapolation filter-based Intra Prediction&#xff0c;EIP&#xff09;模式。首先&#xff0c;利用预定模板从当前块的相邻重建像素获得外推滤波器系数。然后&#xff0c;在当前块内从左上到右下逐位置地处理外推&…

Linux常用命令(3)

文章目录 Linux常用命令&#xff08;3&#xff09;显示文件显示文件内容分屏显示文件内容显示文件前n行&#xff08;默认缺省10行&#xff09;内容显示文件后n行&#xff08;默认缺省10行&#xff09;内容随文件的增长而显示 Linux常用命令&#xff08;3&#xff09; 按ctrlsh…

open3d教程(一):open3d的安装和测试

1 介绍 Open3d&#xff1a;用于3D数据处理的现代库。 Open3D 是一个开源库&#xff0c;支持快速开发处理 3D 数据的软件。 Open3D 前端在 C 和 Python 中公开了一组精心挑选的数据结构和算法。后端经过高度优化&#xff0c;并设置为并行化。我们欢迎来自开源社区的贡献。 2 …

【零基础学机器学习 1】什么是机器学习?

机器学习的社会应用 1. 金融风控 机器学习在金融风控方面的应用非常广泛&#xff0c;可以用于预测借款人的信用风险、欺诈行为等。通过收集大量的历史数据&#xff0c;构建机器学习模型&#xff0c;可以对借款人的信用风险进行预测&#xff0c;从而帮助金融机构降低风险。 2…

关于ADC的笔记1

ADC&#xff0c;全称Anlog-to-Digital Converter&#xff0c;模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件&#xff0c;我们能通过ADC将外界的电压值读入我们的单片机中. 常见的ADC有两种 1.并联比较型&#xff1a; 它的优点是转换速度最快&#x…

[MYSQL / Mariadb]数据库学习-数据类型

数据库学习-数据类型 数据类型字符类型定长char例&#xff1a;定义表结构的定长&#xff1a; 变长 varchar例&#xff1a;创建表&#xff0c;定义变长练习字符类型 数值类型整数(tinyint, smallint, mediumint, int, bigint, unsigned)以mysql> desc mysql.user; 为例例&…

Leetcode697. 数组的度

Every day a leetcode 题目来源&#xff1a;697. 数组的度 解法1&#xff1a;哈希 我们这样构建哈希表 unordered_map<int, vector> umap&#xff1a; key&#xff1a;数组元素 nums[i]value&#xff1a;三元组[count, first, last]&#xff0c;分别代表元素 nums[i]…

Spring03--Spring基于注解的AOP、Spring事务

Spring基于注解的AOP 一、基于注解的AOP介绍 AOP注解方式 和 XML方式完成的功能是一样&#xff0c;只是采用方式不同而已。将原有的XML方式使用注解注意替代 二、环境搭建 使用Spring02中Spring基于配置文件的AOP的环境搭建 三、使用注解替换XML的配置步骤 1、通知类使用…

边缘化你必须知道的一件事!(FEJ知识点总结)

vins和g2o边缘化的异同&#xff1a;(已经做到ppt里面了&#xff0c;简单回顾一下) 1.《视觉slam14讲》中提及的边缘化(G2O边缘化)是在计算求解过程中&#xff0c;先消去路标点变量&#xff0c;实现先求解相机位姿&#xff0c;然后再利用求解出来的相机位姿反过来计算路标点的过…

qt creator添加build步骤删除某个文件

参考&#xff1a;https://blog.csdn.net/weixin_44436546/article/details/113587115 1. windows下配置&#xff1a; 添加build步骤&#xff1b;在commad栏输入cmd,会弹出C:\Windows\system32\cmd.exe&#xff1b;在Arguments栏输入/c release\upgrade.o&#xff1b;Working …

【数据结构】C语言实现双向链表(带头结点、循环)

C语言实现双向链表&#xff08;带头结点、循环&#xff09; 一、带头结点的循环双向链表二、结点与接口定义三、实现3.1 申请节点3.2 初始化3.3 打印3.4 尾插3.5 头插3.6 尾删3.7 判断链表为空断言3.8 头删3.9 查找find3.10 插入insert-在pos之前插入3.11 头插尾插复用insert3.…

机器学习算法实战(scikit-learn版本)---线性回归

目录 文章目标&#xff1a; 1&#xff0c;导入库 2&#xff0c;导入数据集 3&#xff0c;缩放/归一化训练数据 4,创建并拟合回归模型 5,查看参数 6,预测 7&#xff0c;可视化 有一个开源的、商业上可用的机器学习工具包&#xff0c;叫做[scikit-learn](https://scik…

阿里、京东等大厂年薪50w的测试都是什么水平?

各位做测试的朋友&#xff0c;但凡经历过几次面试&#xff0c;那么你一定曾被问到过以下问题&#xff1a; 1、在Linux环境下&#xff0c;怎么执行web自动化测试&#xff1f; 2、Shell如何&#xff0c;Docker熟悉吗&#xff1f; 3、全链路的压测实操过吗&#xff0c;如何推进与开…

【Linux】基本权限

&#x1f601;作者&#xff1a;日出等日落 &#x1f514;专栏&#xff1a;Linux 任何值得到达的地方&#xff0c;都没有捷径。 目录 Linux权限: 权限的概念&#xff1a; Linux上面的用户分类&#xff1a; Linux权限管理 文件访问者的分类&#xff08;人&#xff09; 文件…

小心白蛇!PyPI仓库被持续投放White Snake后门组件

背景 墨菲安全实验室在持续监测开源软件仓库中的投毒行为&#xff0c;4 月 14 日起陆续发现至少 41 个包含白蛇&#xff08;White Snake&#xff09;后门的 Python 包被发布到 PyPI 仓库&#xff0c;目前相关的后门包仍在持续发布。 事件简述 白蛇 &#xff08;WhiteSnake&a…

三种方法教你让模糊照片秒变高清图

现在随着数字相机和智能手机的普及&#xff0c;我们拍摄的照片数量越来越多&#xff0c;但是有些照片可能因为环境或技术等原因导致模糊不清&#xff0c;这时候我们就需要使用一些软件或工具来让照片变得清晰&#xff0c;以满足我们的需求。 下面介绍三种常用的照片变清晰的方…

专科生学习云计算的就业前景如何?

作为专科学历学习云计算&#xff0c;就业前景肯定是有的。因为目前开设云计算这门专业主要也是专科院校&#xff0c;目前入行的学历要求也是专科为起点&#xff0c;更加侧重技术技能水平&#xff0c;技术过关了才能找到合适的工作。 云计算作为一种新兴的IT技术方向&#xff0…

AI别来搅局,chatGPT的世界不懂低代码

ChatGPT单月访问量再创新高 根据SimilarWeb统计&#xff0c;ChatGPT上月全球访问量17.6亿次&#xff0c;已超越必应、鸭鸭走DuckDuckGo等其他国际搜索引擎&#xff0c;并达到谷歌的2%&#xff0c;百度的60%。 这会&#xff0c;程序员失业的段子又得再来一遍了&#xff1a; 拖…

Qt+WebRTC学习笔记(七)ubuntu22.04下搭建coturn(STUN/TURN)

前言 因工作原因&#xff0c;很长时间没更新相关文档了&#xff0c;笔者之前测试时&#xff0c;一直使用示例自带的公网中转服务器。考虑到后期项目需要&#xff0c;笔者在线搭建一个coturn服务器测试&#xff0c;供有需要的小伙伴使用 一、安装coturn 若需要最新版本的cotu…