基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查

基于SSM框架的《超市订单管理系统》Web项目开发(第五天)供应商管理,增删改查

上一次我们实现了多表关联查询,还有分页显示数据的功能。还完善了用户管理这一模块。

因此今天我们需要完成的是供应商管理模块,这一模块与用户管理模块都是需要我们进行分页查询和

删除提示。(基本是跟用户管理这一模块相差不大,所以今天的进度会快速一点,不过会着重讲解一下,如何获取在前端获取后端传送的信息,并且前端如何传递信息到后端去,这一部分的话就是用户体验模块

(PS:近期有事所以没有更新,会找时间再更新的)


在这里插入图片描述

今天要完成的功能有:

  1. 实现供应商的添加功能
  2. 实现供应商的修改功能
  3. 实现供应商的查看功能,包括搜索功能
  4. 实现供应商的删除功能

可以好好回想一下,前后端数据传递的知识(view怎么通过表单把数据传给controller端,controller端怎么通过model把数据传给view端


一、实现供应商界面provider.jsp(归属于查询的一方面)

在这里插入图片描述

首先看这张需求图,那么我们就要判断出,页面中我们需要获取的参数有哪些?

可以看到,我们需要在前端往后端传的参数有:

1.供应商名(查询用的),这个我们是需要把以这个参数进行查询,希望获取到结果的集合

2.页面索引(分页使用,应该在前端页面中设置一个隐藏起来的参数,其作用是用于记录当前页码)

在这里插入图片描述

​ **代码解释一下:**因为这里我们是进行一个供应商列表查询,我们需要对结果进行分页显示。pageIndex是一个用于记录当前页码的变量,它的值会随着用户翻页操作而不断变化。因此需要从前端传回到后端,以获取对应的供应商数据。

为了将当前页码的值传递到后台,需要将pageIndex的值存储到表单中,并将表单提交到后台。而为了避免用户看到或修改页码,可以将pageIndex设置为一个隐藏的参数,这样它就不会在页面上显示出来。而后台就可以根据该参数值,正确地展示对应的供应商数据了


那么我们先放一下,就按照我们之前说的后端流程来进行开发

熟悉pojo->dao->service->controller->view的过程

①链接数据库自动创建provider数据表的pojo类

在这里插入图片描述

详细过程不展示了,可以翻看查阅我的往期文章➡使用idea链接数据库自动生成数据表的pojo类

PS:生成完一定要记得自己去检查一下pojo类!(如下图)

  • 是否导包正确,路径是否正确
  • 字段映射的变量属性是否正确?

在这里插入图片描述


②编写dao层中的ProviderMapper.xml,查询供应商列表的sql语句

1.我们需要一个根据条件查询供应商总数的sql语句:getProviderCount

2.还需要一个对供应商表分页的查询的sql语句:getProviderListByPage

<!--查询供应商总数的统计-->
<select id="getProviderCount" resultType="int">
    select  count(1) as count from provider
    <where>
        <if test="proName!=null and proName!=''">
            proName like CONCAT ('%',#{proName},'%')
        </if>
    </where>
</select>

<!--创建一个对供应商表分页的查询-->
<select id="getProviderListByPage" resultType="Provider">
    select  * from provider
    <where>
        <if test="proName!=null and proName!=''">
            proName like CONCAT ('%',#{proName},'%')
        </if>
    </where>
    order by id limit #{currentPageNo},#{pageSize}
</select>

这里我们使用了动态sql

  • 若是proName不为空,则根据proName进行模糊查询出所有相关的供应商.
  • 若是proName为空,那么直接就默认查询全部的供应商列表。

若是对动态SQL不熟悉的话,可以参考我往期的文章学习下关于动态SQL的知识

什么是动态SQL,如何应用?


③编写ProviderMapper接口,往里面加入对应sql语句,记得方法名要与Provider.xml中的sql的id一致
//获取供应商记录总数
public int getProviderCount(@Param("proName")String proName);

//根据条件查询供应商列表
public List<Provider> getProviderListByPage(@Param("proName")String proName,
                                            @Param("currentPageNo")Integer currentPageNo,
                                            @Param("pageSize")Integer pageSize);

PS:方法的参数和返回类型要与SQl语句中设置的一致,不然会出现参数报错,什么类型不符等报错

在这里插入图片描述


④编写ProviderService接口,往里面加入getProviderCount、getProviderListByPage方法

在这里插入图片描述

⑤编写ProviderServiceImpl实现类,实现getProviderCount、getProviderListByPage方法的具体细节。

在这里插入图片描述

PS:代码就不解释了,这和前面的用户模块代码相似,面向接口编程。这俩个是为了初始化供应商页面的时候能够获取到所有供应商信息和进行信息分页展示。


⑥编写Controller层,新建一个ProviderController类。一般来说,对不同的类进行操作,我们会编写不同的controller类。

前面User表的增删改查,所有的信息主体都是User表,因此我们创建UserController类进行控制。

那么现在我们对Provider表进行增删改查,因此我们也可以新建一个ProviderController类进行控制,这样分开来编写,后续新功能的拓展或者修改,都不会影响到其他的功能运行。

(这也是有点分布式的意思在里面,提前了解,可以帮助我们以后更快掌握分布式)

在这里插入图片描述

这里就不讲解了,和UserController类似。俩个参数,一个是页面当前页索引,二是需要查询的供应商名。

//获取供应商列表
@RequestMapping(value="/providerlist")
public String getProviderList(Model model,HttpSession session,
                          @RequestParam(value="queryname",required=false) String queryProviderName,
                          @RequestParam(value="pageIndex",required=false) String pageIndex) {
    logger.info("用户进入providerlist,供应商列表界面");
    if(session.getAttribute("user") == null){ //如果用户没有登录就直接来到provider就回到syserror
        return "redirect:/syserror";
    }

    List<Provider> providerList = null;
    //设置页面容量
    int pageSize = 5;
    //当前页码
    int currentPageNo = 1;

    if(queryProviderName == null){
        queryProviderName = "";
    }


    if(pageIndex != null){
        try{
            currentPageNo = Integer.valueOf(pageIndex);
        }catch(NumberFormatException e){
            return "redirect:/syserror";
        }
    }
    //总数量(表)
    int totalCount = providerService.getProviderCount(queryProviderName);
    //总页数
    PageSupport pages=new PageSupport();
    pages.setCurrentPageNo(currentPageNo);
    pages.setPageSize(pageSize);
    pages.setTotalCount(totalCount);
    int totalPageCount = pages.getTotalPageCount();

    //控制首页和尾页

    //设置分页的每一页的显示从哪里开始
    int start = ((currentPageNo-1) * pageSize);

    if(currentPageNo < 1){
        currentPageNo = 1;
    }else if(currentPageNo > totalPageCount){
        currentPageNo = totalPageCount;
    }


    //若是想要展示出其他的信息,就需要在这部分,把对应的数据或者变量添加到model中,然后去前端设置接受参数即可。
    providerList = providerService.getProviderListByPage(queryProviderName,start,pageSize);
    model.addAttribute("providerList", providerList);
    model.addAttribute("queryProviderName", queryProviderName);
    model.addAttribute("totalPageCount", totalPageCount);
    model.addAttribute("totalCount", totalCount);
    model.addAttribute("currentPageNo", currentPageNo);
    return "provider";
}

写入了一个名为providerlist的映射,所以当访问providerlist的网址时,我们会跳转到provider的视图view中,因此得去创建一下provider.jsp。


⑦编写provider.jsp,记得在自己项目设定的路径下创建嗷
<%--
  Created by IntelliJ IDEA.
  User: Stevedash
  Date: 2023/9/18
  Time: 18:52
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@include file="/WEB-INF/pages/common/head.jsp"%>
<div class="right">
    <div class="location">
        <strong>你现在所在的位置是:</strong>
        <span>供应商管理页面</span>
    </div>
    <div class="search">
        <form method="post" action="${pageContext.request.contextPath }/providerlist">
            <input name="method" value="query" class="input-text" type="hidden">
            <span>供应商名:</span>
            <input name="queryname" class="input-text" type="text" value="${queryProviderName }">
            <input type="hidden" name="pageIndex" value="1"/>
            <input value="查 询" type="submit" id="searchbutton">
            <a href="${pageContext.request.contextPath}/provideradd" >添加供应商</a>
        </form>
    </div>
    <!--用户-->
    <table class="providerTable" cellpadding="0" cellspacing="0">
        <tr class="firstTr">
            <th width="10%">供应商编码</th>
            <th width="20%">供应商名称</th>
            <th width="10%">联系人</th>

            <th width="10%">电话</th>
            <th width="20%">供应商地址</th>
            <th width="30%">操作</th>
        </tr>

<c:forEach var="provider" items="${providerList }" varStatus="status">

            <tr>
                <td>${provider.proCode}</td>
                <td>${provider.proName}</td>
                <td>${provider.proContact}</td>
                <td>${provider.proPhone}</td>
                <td>${provider.proAddress}</td>


                <td>
                    <span><a class="viewProvider" href="javascript:;" providerid=${provider.id} proCode=${provider.proCode } ><img src="${pageContext.request.contextPath }/statics/images/read.png" alt="查看" title="查看"/></a></span>
                    <span><a class="modifyProvider" href="javascript:;" providerid=${provider.id } proCode=${provider.proCode }><img src="${pageContext.request.contextPath }/statics/images/xiugai.png" alt="修改" title="修改"/></a></span>
                    <span><a class="deleteProvider" href="javascript:;" providerid=${provider.id } proCode=${provider.proCode }><img src="${pageContext.request.contextPath }/statics/images/schu.png" alt="删除" title="删除"/></a></span>
                </td>
            </tr>
        </c:forEach>
    </table>

    <input type="hidden" id="totalPageCount" value="${totalPageCount}"/>
    <c:import url="rollpage.jsp">
        <c:param name="totalCount" value="${totalCount}"/>
        <c:param name="currentPageNo" value="${currentPageNo}"/>
        <c:param name="totalPageCount" value="${totalPageCount}"/>
    </c:import>
</div>
</section>

<!--点击删除按钮后弹出的页面-->
<div class="zhezhao"></div>
<div class="remove" id="removeProv">
    <div class="removerChid">
        <h2>提示</h2>
        <div class="removeMain">
            <p>你确定要删除该供应商吗?</p>
            <a href="#" id="yes">确定</a>
            <a href="#" id="no">取消</a>
        </div>
    </div>
</div>

<%@include file="/WEB-INF/pages/common/foot.jsp" %>
<script type="text/javascript" src="${pageContext.request.contextPath }/statics/js/providerlist.js"></script>

基本页面的展示和用户管理页面相差不大,唯一需要讲解的就是

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

这是在JSP页面中导入JSTL(JavaServer Pages Standard Tag Library)的核心功能库。JSTL是一个非常流行的标准标签库,它为JSP页面提供了一系列的标准动作,比如迭代、条件判断、国际化支持、SQL等

因此我们遍历集合中的数据就更为简单轻松!!!


⑧运行项目进行测试,出现如下报错

在这里插入图片描述

PS:这种是编码错误,因为我们的代码中有中文注释嘛,不过呢没有影响的,我们前面也设定好了项目文件的编码,这里会提示报错,是因为编译器中的预编译设置,我们对项目文件有了修改,他检查到与项目编码不同,所以弹出的报错

​ 实际上我们只需要再点击一次项目运行即可正常部署!!!

在这里插入图片描述

在这里插入图片描述

正常部署啦,打开网页输入我们设置好的映射网址进行尝试把

在这里插入图片描述

正确显示啦,若是弹出404等,就说明还没有修改页面的指针,得去common下找到头部文件head.jsp,里面修改一下我们侧边栏指引的跳转路径,修改成我们前面设置好的providerlist映射即可。

在这里插入图片描述

下面的三个功能也是基本上一致的,需要同学们自己完成┗|`O′|┛ 嗷~~,要考虑的就是需要什么参数,是否需要返回值,也就是考虑方法设计的同时,需要想到的点。

想要跟着学习的可以去我的资源里面找对应的文件下载,我的md文件也会发上去,项目文件会上传可以自己跟着学习一下。

作者:Stevedash

发表于:2023年12月4日 23点39分

注:本文内容基于个人学习理解,如有错误或疏漏,欢迎指正。感谢阅读!如果觉得有帮助,请点赞和分享。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简单了解传输层协议之TCP和UDP

目录 一、什么是端口号? 二、TCP协议 2.1 TCP报文格式 2.2 三次握手 2.3 四次挥手 2.4 窗口流量控制 三、UDP协议 3.1 UDP报文格式 3.4 传输过程 一、什么是端口号? 我们自己的一台电脑上有时可能会同时运行多个进程软件来进行上网。那么当网络上的服务器响应我们电…

3 开发环境搭建

一、Ubuntu和Windows文件互传 ① 开启Ubuntu的FTP服务&#xff1a; 下载vsftpd&#xff1a;sudo apt-get install vsftpd; 打开vsftpd.conf&#xff1a;sudo nvim /etc/vsftpd.conf; 确保这两行代码没有被注释&#xff1a; 之后重启FTP服务&#xff1a; ② Windows下载FTP客…

LinuxBasicsForHackers笔记 -- 控制文件和目录权限

对于每个文件和目录&#xff0c;我们可以指定文件所有者、特定用户组以及所有其他用户的权限状态。 不同类型的用户 在Linux中&#xff0c;root用户是拥有一切权力的。 root 用户基本上可以在系统上执行任何操作。 系统上的其他用户具有有限的能力和权限&#xff0c;并且几乎…

为什么 SQL 不适合图数据库

背景 “为什么你们的图形产品不支持 SQL 或类似 SQL 的查询语言&#xff1f;” 过去&#xff0c;我们的一些客户经常问这个问题&#xff0c;但随着时间的推移&#xff0c;这个问题变得越来越少。 尽管一度被忽视&#xff0c;但图数据库拥有无缝设计并适应其底层数据结构的查询…

nodejs微信小程序+python+PHP就业求职招聘信息平台的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之文件管理(1)》(22)

《Linux操作系统原理分析之文件管理&#xff08;1&#xff09;》&#xff08;22&#xff09; 7 文件管理7.1 文件与文件系统7.1.1 文件7.1.3 文件系统及其功能 7.2 文件的组织结构7.2.1 文件的逻辑结构7.2.2 文件的物理结构一、顺序结构&#xff08;顺序文件或连续文件&#xf…

微信小程序uni.chooseImage()无效解决方案

Bug场景&#xff1a; 微信小程序在上传图片时可以通过 uni.chooseImage()方案进行上传&#xff0c;这里不再赘述具体参数。一直项目都可以正常使用&#xff0c;突然有一天发现无法使用该方法&#xff0c;于是查了一下&#xff0c;发现是用户隐私协议问题。故记录一下解决方案。…

Linux中的网络配置

本章主要介绍网络配置的方法 网络基础知识查看网络信息图形化界面修改通过配置文件修改 1.1 网络基础知识 一台主机需要配置必要的网络信息&#xff0c;才可以连接到互联网。需要的配置网络信息包括IP、 子网掩码、网关和 DNS 1.1.1 IP地址 在计算机中对IP的标记使用的是3…

逻辑回归 使用Numpy实现逻辑回归

使用Numpy实现逻辑回归 sigmoid 函数 g ( z ) 1 ( 1 e − z ) g(z)\frac{1}{(1e^{−z} )} g(z)(1e−z)1​ # sigmoid 函数 def sigmod(z):return 1/(1np.exp(-z))线性计算与梯度下降 J ( θ ) − 1 m [ ∑ i 1 m y ( i ) l o g ⁡ ( h θ ( x ( i ) ) ) ( 1 − y ( i ) …

【计算机网络笔记】物理层——物理介质

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Linux socket编程(10):UDP详解、聊天室实现及进阶知识

首先来回顾以下TCP的知识&#xff0c;TCP是一种面向连接的、可靠的传输协议&#xff0c;具有以下特点&#xff1a; TCP通过三次握手建立连接&#xff0c;确保通信的可靠性和完整性使用流控制和拥塞控制机制&#xff0c;有效地调整数据传输的速率&#xff0c;防止网络拥塞TCP提…

redis的keys命令和scan命令性能对比

项目场景 Redis的keys *命令在生产环境是慎用的&#xff0c;特别是一些并发量很大的项目&#xff0c;原因是Redis是单线程的&#xff0c;keys *会引发Redis锁&#xff0c;占用reids CPU&#xff0c;如果key数量很大而且并发是比较大的情况&#xff0c;效率是很慢的&#xff0c…

vivado实现分析与收敛技巧9-分析使用率统计数据

实现问题的常见原因之一是未考量显式和隐式物理约束。例如 &#xff0c; 管脚分配 (pinout) 在逻辑布局上变为显式物理约束。 slice&#xff08; 分片 &#xff09; 逻辑在大部分器件中都是一致的。但如下专用资源表示的是隐式物理约束 &#xff0c; 因为这些资源仅在某些位置…

C语言碎片知识

sizeof 1.sizeof是C语言中的一个操作符&#xff0c;同时也是关键字&#xff01;&#xff01;&#xff01;&#xff01; 2.sizeof的操作数可以是类型&#xff0c;变量或表达式 如图&#xff0c;第一个为什么是6&#xff1f;&#xff0c;因为先计算了3的大小&#xff0c;占4个字…

【模电】放大电路的组成原则

放大电路的组成原则 组成原则常用的两种共射放大电路 组成原则 通过对基本共射放大电路的简单分析可以总结出&#xff0c;在组成放大电路时必须遵循以下几个原则&#xff1a;    1. 必须根据所用放大管的类型提供直流电源&#xff0c;以便设置合适的静态工作点&#xff0c;并…

【unity3D】unity中如何查找和获取游戏物体

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity中游戏物体的查找与获取 这里写自定义目录标题 获取当前物体的基本属性查找其它物体- 通过名称查找其它物体- 通过标签查找- 通过类…

互联网Java工程师面试题·Spring Boot篇·第二弹

目录 8、什么是 YAML&#xff1f; 9、如何实现 Spring Boot 应用程序的安全性&#xff1f; 10、如何集成 Spring Boot 和 ActiveMQ&#xff1f; 11、如何使用 Spring Boot 实现分页和排序&#xff1f; 12、什么是 Swagger&#xff1f;你用 Spring Boot 实现了它吗&#xff1f; …

MySQL之时间戳(DateTime和TimeStamp)

MySQL之时间戳&#xff08;DateTime和TimeStamp&#xff09; 文章目录&#xff1a; MySQL之时间戳&#xff08;DateTime和TimeStamp&#xff09;一、DateTime类型二、TimeStamp类型三、DateTime和TimeStamp的区别 当插入数据时&#xff0c;需要自动记录一个时间时候&#xff0c…

【springboot】整合redis

1.前提条件:docker安装好了redis确定redis可以访问 可选软件: 2.测试代码 (1)redis依赖 org.springframework.boot spring-boot-starter-data-redis (2)配置redis &#xff08;3&#xff09; 注入 Resource StringRedisTemplate stringRedisTemplate; 对键进行操作 –o…