SpringBoot水果商城后台管理系统(文末附源码)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 🍅程序员小王的博客:程序员小王的博客🍅 欢迎点赞 👍 收藏 ⭐留言 📝🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕🍅java自学的学习路线:java自学的学习路线

一、项目功能简介

(1)《SpringBoot水果商城后台管理系统》该项目采用技术:

《SpringBoot水果商城后台管理系统》该项目采用的技术实现如下:HTML+CSS+JavaScript+jsp+SpringBoot+Mybatis+Mysql


后台使用SpringBoot+mybatis框架

前端采用jsp+js+css等界面非常的美观大方

mysql数据库+tomcat服务器


(2)管理员功能介绍:

1、管理员登录(如果验证码错误报:验证码有误,密码或账户错误报账户或密码错误)


2、强制登录,如果管理员没有登录,不能进入系统(显示管理员名字为登录成功)


3、退出登录(注销Session的形式进行退出登录)


8.png

9.png



(3)水果功能介绍:

1、分页展示所有

2、删除

3、批量删除

4、全选

6、修改(先进行数据回显之后进行修改)

7、图片上传和图片在页面显示功能


10.png

11.png

12.png


二、数据库设计

(1)数据库创建

-- 创建员工表
create table admin(
id int primary key auto_increment,
username varchar(20) not null,
password varchar(20) not null
)
-- 添加管理员数据
insert into admin values(null,'王恒杰','123456');
insert into admin values(null,'杨福君','whj63135');
insert into admin values(null,'邓正武','675437');
-- 查询管理员
select *from admin;
-- 创建水果表
create table fruit(
id int primary key auto_increment,
image varchar(30) not null,
name varchar(20) not null,
price double not null,
month int not null,
createTime date
);
-- 查询水果表
select * from fruit;
-- 添加水果信息
insert into fruit values(null,'/img.jpg','苹果','5.00',5,NOW());

(2)数据库设计文档

数据库名: fruitmall

文档版本: V1.0.0

文档描述: 数据库表设计描述

image.png


表名: admin

说明: 管理员

image.png


表名: fruit

说明: 水果

image.png


三、导入项目相关依赖和配置application.yml

(1)导入相关依赖

 

 

  <!--集成springboot的父项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
    <dependencies>
        <!--引入springboot的web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--引入mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!--引入mybatis以及整合相关依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>
        <!--JSTL表达式-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--引入junit测试相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--引入aop相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--jsp-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
    </dependencies>

(2)配置application.yml

server:
  port: 8080 #端口号
  servlet:
    context-path: /fruitmall #水果商城
    jsp:
      init-parameters:
        development: true  #开启jsp页面的调试模式
spring:
  mvc:
    view:
      prefix: /    #前缀
      suffix: .jsp  #后缀
# 数据源
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  #数据源类型
    driver-class-name: com.mysql.cj.jdbc.Driver   #加载驱动
    url: jdbc:mysql://localhost:3306/fruitmall?useSSL=false&serverTimezone=UTC
    username: root
    password: root
mybatis:
  mapper-locations: classpath:com/tjcu/mapper/*Mapper.xml #指定mapper文件所在的位置,其中classpath必须和mapper-locations分开
  type-aliases-package: com.tjcu.entity

四、管理员核心功能

1、前端

<%@page isELIgnored="false" contentType="text/html; harset=utf-8" pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>login</title>
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/bootstrap.min.css"/>
</head>
<body>
<div id="wrap" class="container-fluid">
    <div id="top_content" class="row" style="margin: 0 auto;">
        <div class="col-sm-8 col-sm-offset-2">
            <div id="header">
                <div id="topheader">
                    <h1 class="text-center text-info">欢迎进入水果管理系统V1.0</h1>
                </div>
                <div id="navigation">
                </div>
            </div>
        </div>
    </div>
    <div class="row" style="margin-top: 20px;">
        <div class="col-sm-8 col-sm-offset-2">
            <div id="content">
                <form method="post" action="${pageContext.request.contextPath}/admin/login">
                    <div class="form-group">
                        <label for="username">用户名</label>
                        <input type="text" v-model="username" id="username" class="form-control" name="username"/>
                    </div>
                    <div class="form-group">
                        <label for="password">密码</label>
                        <input type="password" id="password" v-model="password" class="form-control" name="password"/>
                    </div>
                    <br>
                    <tr>
                        <td valign="middle" align="right">
                            验证码:
                            <img id="num" src="${pageContext.request.contextPath}/admin/generateImageCode" />
                            <a href="javascript:;" onclick="document.getElementById('num').src = '${pageContext.request.contextPath}/admin/generateImageCode?'+(new Date()).getTime()">换一张</a>
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="adminCode" />
                        </td>
                    </tr>
                    <input type="submit" style="width: 98%" class="btn btn-danger" value="登录&raquo;"/>
                </form>
            </div>
            ${requestScope.msg}
        </div>
    </div>
    <div class="row" style="margin-top: 40px;">
        <div class="col-sm-8 col-sm-offset-2">
            <h5 class="text-center">Fruit@136.com</h5>
        </div>
    </div>
</div>
</body>
</html>

2、控制层

package com.tjcu.controller;
import com.tjcu.entity.Admin;
import com.tjcu.service.AdminService;
import com.tjcu.utils.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import static javax.swing.text.html.CSS.getAttribute;
/**
 * @author 王恒杰
 * @date 2021/11/28 16:22
 * @Description:
 */
@Controller
@RequestMapping("admin")
public class AdminAction {
    @Autowired
    private AdminService adminService;
    @RequestMapping("login")
    public String login(Admin admin, HttpServletRequest request,String adminCode){
        //1.比较验证是否一致
        HttpSession session = request.getSession();
        String code = session.getAttribute("code").toString();
        if(code.equals(adminCode)){
            Admin login = adminService.login(admin.getUsername(), admin.getPassword());
           if(login!=null){
               request.setAttribute("admin",login);
               session.setAttribute("admin",login);
               return "forward:/fruit/showAll?pageNumber=1";
           }else {
               request.setAttribute("msg","用户名或者密码输入错误");
               return "login";
           }
        }else {
            request.setAttribute("msg","验证码输入错误");
            return "login";
        }
    }
    /**
     * 用来生成验证码方法
     */
    @RequestMapping("generateImageCode")
    public void generateImageCode(HttpSession session, HttpServletResponse response) throws IOException {
        //1.生成随机字符串
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2.保存随机字符串到Session中
        session.setAttribute("code",code);
        //3.将随机字符串生成图片
        //4.通过response响应图片
        response.setContentType("image/png");//指定响应类型
        ServletOutputStream os = response.getOutputStream();
        VerifyCodeUtils.outputImage(80,30,os,code);
    }
@RequestMapping("cancel")
    public String cancel(HttpServletRequest request){
        request.getSession().invalidate();
        request.setAttribute("msg","管理员已经退出登录!");
        return "login";
    }
}

五、水果相关功能核心代码

1、全选jquery实现

<script>
    $("#selectAll").click(function () {
        //:checkbox 获取当前选中的单选按钮或者复选框
        //:checkbox:gt(0) 获取当前复选框大于0的复选框
        //prop修改标签的属性 标签对象.prop(“属性名”,”属性值”);
        //prop获取标签的属性 标签对象.prop(“属性名”);
        //checked:选中
        //注意:在单选框和复选框中checked只要出现checked就是选中,不管他是否等于true还是false
        $(":checkbox:gt(0)").prop("checked",$("#selectAll").prop("checked"))
    })

2、确认删除jquery实现

<%--单个删除--%>
<script>
        function delRow(id,pageNumber){
            if(window.confirm("你确定删除这个商品吗?")){
                location.href="${pageContext.request.contextPath}/fruit/drop?pageNumber="+pageNumber+"&id="+id;
            }
        }
</script>


3、修改和数据回显前端页面

<%@page isELIgnored="false" contentType="text/html; harset=utf-8" pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
\
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>update</title>
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/bootstrap.min.css"/>
</head>
<body>
<div id="wrap">
    <div id="top_content" class="row" style="margin: 0 auto;">
        <div class="col-sm-8 col-sm-offset-2">
            <div id="header">
                <div id="topheader">
                    <h1 class="text-center text-info">欢迎进入水果管理系统V1.0</h1>
                </div>
                <div id="navigation">
                </div>
            </div>
        </div>
    </div>
    <div class="row" style="margin-top: 20px;">
        <div class="col-sm-8 col-sm-offset-2">
            <div id="content">
                <p id="whereami">
                </p>
                <h1>
                    修改水果信息:
                </h1>
                <form action="${pageContext.request.contextPath}/fruit/update" method="post" enctype="multipart/form-data">
                    <input  type="hidden" name="id" value="${requestScope.fruit.id}">
                    <div class="form-group">
                        <label for="name">名称</label>
                        <input type="text" class="form-control" name="name" id="name" value="${requestScope.fruit.name}"
                               placeholder="输入水果名称">
                    </div>
                    <div class="form-group">
                        <label for="price">价格</label>
                        <input type="text" class="form-control" name="price" id="price"
                               value="${requestScope.fruit.price}" placeholder="输入水果价格">
                    </div>
                    <div class="form-group">
                        <label for="age">保质期(单位:月)</label>
                        <input type="text" class="form-control"  id="age" name="month"
                               value="${requestScope.fruit.month}" placeholder="输入水果保质期">
                    </div>
                    <div class="form-group">
                        <label for="photos">水果图片</label>
                        <input type="file" ref="file" id="photos" class="form-control" name="photo"/>
                    </div>
                    <input type="submit"  style="width: 98%" class="btn btn-warning" value="确认修改" />
                </form>
            </div>
        </div>
    </div>
    <div id="footer">
        <div class="row" style="margin-top: 40px;">
            <div class="col-sm-8 col-sm-offset-2">
                <h5 class="text-center">Fruit@136.com</h5>
            </div>
        </div>
    </div>
</div>
</body>
</html>

4、分页前端页面实现

 

     <%--colspan:跨列数--%>
                        <td colspan="7" align="center">
                            <c:if test="${requestScope.pageNumber>1}">
                                <a href="${pageContext.request.contextPath}/fruit/showAll?pageNumber=${requestScope.pageNumber-1}">上一页</a>
                            </c:if>
                            <c:if test="${requestScope.pageNumber<=1}">
                                上一页
                            </c:if>
                            <%--当前页数--%>
                            <c:forEach begin="1" end="${requestScope.totalPage}" var="page">
                                <a href="${pageContext.request.contextPath}/fruit/showAll?pageNumber=${page}">${page}</a>
                            </c:forEach>
                            <%--下一页数--%>
                            <c:if test="${requestScope.pageNumber<requestScope.totalPage}">
                                <a href="${pageContext.request.contextPath}/fruit/showAll?pageNumber=${requestScope.pageNumber+1}">下一页</a>
                            </c:if>
                            <c:if test="${requestScope.pageNumber>=requestScope.totalPage}">
                                下一页
                            </c:if>
                        </td>
                    </tr>

5、Controller层

/**
 * @author 王恒杰
 * @date 2021/11/27 23:38
 * @Description:
 */
@Controller
@RequestMapping("fruit")
public class FruitAction {
    @Autowired
    private FruitService fruitService;
    /**
     * 添加水果
     */
    @RequestMapping("add")
    public String add(MultipartFile photo, Fruit fruit,HttpServletRequest request) throws IOException {
        //获取文件存储的真实路径
        String realPath = request.getSession().getServletContext().getRealPath("photo");
        //文件拷贝
        photo.transferTo(new File(realPath,photo.getOriginalFilename()));
        //水果的图片名
        fruit.setImg(photo.getOriginalFilename());
        fruitService.add(fruit);
        return "redirect:/fruit/showAll?pageNumber=1";
    }
    /**
     * 修改水果
     */
    @RequestMapping("update")
    public String update(MultipartFile photo, Fruit fruit,HttpServletRequest request) throws IOException {
        //获取文件存储的真实路径
        String realPath = request.getSession().getServletContext().getRealPath("photo");
        //文件拷贝
        photo.transferTo(new File(realPath+"/"+photo.getOriginalFilename()));
        //水果的图片名
        fruit.setImg(photo.getOriginalFilename());
        //修改时间
        fruit.setCreatTime(new Date());
        fruitService.update(fruit);
        return "redirect:/fruit/showAll?pageNumber=1";
    }
    /**
     * 查询水果 数据回显
     */
    @RequestMapping("query")
    public String query(Integer id, HttpServletRequest request) {
        System.out.println(id);
        Fruit query = fruitService.query(id);
        System.out.println(query);
        request.setAttribute("fruit", query);
        return "update";
    }
    /**
     * 删除水果
     */
    @RequestMapping("drop")
    public String drop(Fruit fruit,Integer pageNumber) {
        System.out.println(pageNumber);
        System.out.println(fruit.getId());
        fruitService.drop(fruit.getId());
        return "redirect:/fruit/showAll?pageNumber="+pageNumber;
    }
    /**
     * 批量删除
     */
    @RequestMapping("batchDelete")
    public String batchDelete(Collection collection) {
        fruitService.batchDelete(collection.getIds());
        return "redirect:/fruit/showAll?pageNumber=1";
    }
    /**
     * 分页实现
     */
    @RequestMapping("showAll")
    public String pageFruit(Integer pageNumber,HttpServletRequest request) {
        List<Fruit> fruits = fruitService.pageFruit(pageNumber);
        request.setAttribute("fruits",fruits);
        //当前页
        request.setAttribute("pageNumber",pageNumber);
        //总页数
        Integer integer = fruitService.TotalPage();
        request.setAttribute("totalPage",integer);
        return "showAll";
    }
}

六、源码下载及使用攻略

源码已经上传到gitee上面了,


原创不易,如果觉得不错请给我一个三连、点赞、收藏、加关注!!!


需要源码资料的同学可以去我gitee的下载源码


gitee地址:《SpringBoot水果商城后台管理系统》下载相关源码



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22天前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
52 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
22天前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
93 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
3天前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
77 1
|
22天前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
28 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
15天前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。
|
JSON Java 数据格式
springboot后台下载文件报错: Could not find acceptable representation
使用springboot实现从服务器下载文件功能时,报错:Could not find acceptable representation
1471 0
|
12天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
81 1
|
2月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
108 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
2月前
|
前端开发 JavaScript Java
SpringBoot项目部署打包好的React、Vue项目刷新报错404
本文讨论了在SpringBoot项目中部署React或Vue打包好的前端项目时,刷新页面导致404错误的问题,并提供了两种解决方案:一是在SpringBoot启动类中配置错误页面重定向到index.html,二是将前端路由改为hash模式以避免刷新问题。
148 1
|
13天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
22 3