• 水果库存系统(SSM+Thymeleaf版)


    不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。


    一、前言

    本系统是一个简易版的水果库存系统,在前面的文章里面也有写过 水果库存基础版水果库存进阶版这两个版本的区别是基础版是使用javaSE的知识,进阶版是使用了Spring框架技术,特别是合理的理由了IOC(控制反转)进行重构;如果有兴趣的小伙伴可以点击对应链接查看详情。 而编写本篇文章目的是为了把页面以网页的形式展现出来。而该篇文章适合人群是刚学会SSM框架但是不太懂怎么整合的小伙伴,也适合不知道前端和后端怎么联调开发流程的小伙伴。所以本系统会从0到1完整的开发流程进行讲解。

    二、系统架构与需求分析

    1、技术栈

    1.1 后端

    ① JDK8
    ② IDEA(2022)
    ③ Maven 3.8.3
    ④ Tomcat 8.0
    ⑤ Spring、SpringMVC 5.3.20
    ⑥ Mybatis 3.5.7
    ⑦ Mybatis-Spring 2.0.6
    ⑧ MySQL 8.0.22
    ⑨ Thymeleaf 3.0.15

    1.2 前端

    ① HTML
    ② CSS
    ③ JQuery
    ④ AJAX

    以上就是本系统使用到技术栈,如果你已经学习了以上知识,但是又不知道怎么运用,那么本篇文章会一一进行讲解。

    2、需求分析

    我们先来看看项目的总体结构:
    项目结构图
    由上图所示可以知道,我们的项目是以maven的形式进行搭建的。系统架构使用了常见的MVC三层架构进行实现。本项目不是使用前后端分离的,而是使用了模板引擎Thymeleaf进行页面渲染。 然后就是功能分析;本系统实现了常见的CRUD功能。就是查询水果库存(包含分页)新增水果库存,修改水果库存和删除水果库存。 不过在开发功能之前我们要先做一些准备工作,首先得有存数据的仓库— 数据库,所以我们先来设计一下数据库。

    三、设计数据库

    本系统的数据库设计比较简单,就一个表就可以了,我这里把该表名为t_fruit,该表设计如下:

    字段名数据类型非空自增注释
    fidintyesyes主键编号
    fnamevarchar(20)yesno-名称
    priceintnono-单价
    fcountintnono-数量
    remarkvarchar(50)nono-广告词
    producervarchar(10)nono-产地

    SQL语句如下所示

    # 创建一个名为fruitdb的数据库
    CREATE DATABASE fruitdb;
    # 进入数据库fruitdb
    USE fruitdb;
    # 创建数据表t_fruit
    CREATE TABLE `t_fruit` (
      `fid` int NOT NULL AUTO_INCREMENT COMMENT '编号',
      `fname` varchar(20) NOT NULL COMMENT '名称',
      `price` int DEFAULT NULL COMMENT '单价',
      `fcount` int DEFAULT NULL COMMENT '数量',
      `remark` varchar(50) COMMENT '广告词',
      `producer` varchar(10) COMMENT '产地',
      PRIMARY KEY (`fid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    通过以上的SQL语句就可以创建一个数据库和数据表,现在有了数据表,那么接下来就要开始从后端到前端的开发了。我们先从后端开始>>>

    四、后端篇

    1、环境搭建

    后端的任何功能的开始,都必须有一个环境,所以我们先来搭建一个SSM环境出来。本系统IDE使用IDEA进行开发,而且是基于maven的,具体搭建步骤如下:
    idea项目搭建第一步

    [idea项目搭建第二步]
    以上步骤就已经创建了一个基础maven项目。接下来要配置一下maven:

    maven配置
    由于我们本系统的页面是网页的形式,所以我们还需要在maven上添加web模块,具体步骤如下:

    web模块
    到此本系统的Web项目就创建完成了,项目结构如下所示:项目结构
    项目创建完毕之后,那么就该导入依赖了,和我们以前导入Jar包是一个意思。之前是我们自己导入每一个Jar包,但是有了maven之后,那么我们只要导入对应的坐标依赖就行了,至于Jar包maven会帮我们下载下来。依赖导入是在pom.xml文件中进行编写,本系统使用到的依赖有如下:

    <dependencies>
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-webmvcartifactId>
                <version>5.3.20version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-jdbcartifactId>
                <version>5.3.20version>
            dependency>
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-aspectsartifactId>
                <version>5.3.20version>
            dependency>
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-txartifactId>
                <version>5.3.20version>
            dependency>
    
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.22version>
            dependency>
    
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatisartifactId>
                <version>3.5.7version>
            dependency>
    
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatis-springartifactId>
                <version>2.0.6version>
            dependency>
    
            
            <dependency>
                <groupId>org.thymeleafgroupId>
                <artifactId>thymeleaf-spring5artifactId>
                <version>3.0.15.RELEASEversion>
            dependency>
        dependencies>
    
        
        <build>
            <resources>
                <resource>
                    <directory>src/main/javadirectory>
                    <includes>
                        <include>**/*.propertiesinclude>
                        <include>**/*.xmlinclude>
                    includes>
                    <filtering>falsefiltering>
                resource>
                <resource>
                    <directory>src/main/resourcesdirectory>
                    <includes>
                        <include>**/*.propertiesinclude>
                        <include>**/*.xmlinclude>
                    includes>
                    <filtering>falsefiltering>
                resource>
            resources>
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    到此,本项目的构建已经初步完成了,但是到真正编写功能模块还得配置几个文件才可以,项目有些基础的小伙伴已经知道接下来要做的步骤了,那就是整合SSM。

    2、SSM整合(配置文件编写)

    接下来就是SSM整合,本质上就是进行一些xml配置文件的配置,而我们需要怎么配置呢?我们这里可以分成6个文件;分别为:database.properties(数据库参数文件)、mybatis-config.xml(Mybatis核心配置文件)、spring-dao.xml(Mybatis与Spring整合文件/持久层配置文件)、spring-service.xml(业务层配置文件)、spring-mvc.xml(SpringMVC控制层配置文件)和applicationContext.xml(整合配置文件)。好了,废话不多说,直接开干~

    2.1 database.properties文件编写:

    # 驱动
    jdbc.driver=com.mysql.cj.jdbc.Driver
    # 如果数据库MySQL8+以上需要在后面设置时区 &serverTimezone=UTC
    jdbc.url=jdbc:mysql://localhost:3306/fruitdb?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    # 自己本地数据库账号 和密码
    jdbc.username=root
    jdbc.password=root
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 mybatis-config.xml编写:

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        settings>
        
        
        
        <typeAliases>
            <package name="pojo"/>
        typeAliases>
    
       
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.3 spring-dao.xml编写:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        
        <context:property-placeholder location="classpath:database.properties"/>
    
        
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        bean>
    
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
        bean>
    
        
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
            
            <property name="basePackage" value="mapper"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2.4 spring-service.xml编写:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           https://www.springframework.org/schema/context/spring-context.xsd">
    
        
        <context:component-scan base-package="service"/>
    
        
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.5 spring-mvc.xml编写:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        
        <mvc:annotation-driven/>
        
        <mvc:resources mapping="/css/**" location="/WEB-INF/pages/css/"/>
        <mvc:resources mapping="/js/**" location="/WEB-INF/pages/js/"/>
        <mvc:resources mapping="/images/**" location="/WEB-INF/pages/images/"/>
    
        
        <context:component-scan base-package="controller"/>
        
        
        <bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
            
            <property name="prefix" value="/WEB-INF/pages/">property>
            
            <property name="suffix" value=".html">property>
            
            <property name="characterEncoding" value="utf-8">property>
            
            <property name="cacheable" value="false">property>
            
            <property name="templateMode" value="HTML5">property>
        bean>
    
        
        <bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
            <property name="templateResolver" ref="templateResolver">property>
        bean>
        
        <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
            <property name="characterEncoding" value="utf-8">property>
            <property name="templateEngine" ref="templateEngine">property>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.6 applicationContext.xml编写:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        
        <import resource="classpath:spring-dao.xml"/>
        <import resource="classpath:spring-service.xml"/>
        <import resource="classpath:spring-mvc.xml"/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    本文件配置的目的是为了把三个文件整合起来变成一个文件,到后面启动项目的时候,利用Tomcat初始化配置把该文件作为接口加载即可。

    3、web.xml文件配置(重点)

    ☆☆☆本文件特别重要,如果本文件没有配置,那么当访问页面的时候会出现404。原因是本配置是暴露给浏览器的。本文件是在WEB-INF目录下,具体配置如下所示:

    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        
        <servlet>
            <servlet-name>springmvcservlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
            <init-param>
                
                <param-name>contextConfigLocationparam-name>
                <param-value>classpath:applicationContext.xmlparam-value>
            init-param>
            
            <load-on-startup>1load-on-startup>
        servlet>
        
        <servlet-mapping>
            <servlet-name>springmvcservlet-name>
            <url-pattern>/url-pattern>
        servlet-mapping>
    
        
        <filter>
            <filter-name>encodingFilterfilter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
            <init-param>
                <param-name>encodingparam-name>
                <param-value>utf-8param-value>
            init-param>
        filter>
        
        <filter-mapping>
            <filter-name>encodingFilterfilter-name>
            <url-pattern>/*url-pattern>
        filter-mapping>
    
        
        <session-config>
            <session-timeout>15session-timeout>
        session-config>
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    到此,本系统的所有配置就已经完毕,SSM整合也到此完成了,接下来就可以开始后端功能的编写了。

    4、持久层(Mapper) 编写

    我们先来编写持久层,也就是操作数据库的功能,不过在编写之前,我们得先创建一个与数据表对应的实体类, 具体代码如下:

    package pojo;
    /**
     * 水果库存实体类
     */
    public class Fruit {
        private Integer id; //编号
        private String name; //名称
        private Float price; //单格
        private Integer count; //数量
        private String remark; //广告词
        private String producer; //产地
    
    	//构造
        public Fruit() {
        }
    
        public Fruit(Integer id, String name, Float price, Integer count, String remark, String producer) {
            this.id = id;
            this.name = name;
            this.price = price;
            this.count = count;
            this.remark = remark;
            this.producer = producer;
        }
    	
    	//getting、setting
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Float getPrice() {
            return price;
        }
    
        public void setPrice(Float price) {
            this.price = price;
        }
    
        public Integer getCount() {
            return count;
        }
    
        public void setCount(Integer count) {
            this.count = count;
        }
    
        public String getRemark() {
            return remark;
        }
    
        public void setRemark(String remark) {
            this.remark = remark;
        }
    
        public String getProducer() {
            return producer;
        }
    
        public void setProducer(String producer) {
            this.producer = producer;
        }
    
        @Override
        public String toString() {
            return "Fruit{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", price=" + price +
                    ", count=" + count +
                    ", remark='" + remark + '\'' +
                    ", producer='" + producer + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    数据映射已经编写完成,接下来就是功能实现了,持久层代码如下:

    package mapper;
    
    import org.apache.ibatis.annotations.*;
    import org.apache.ibatis.session.RowBounds;
    import pojo.Fruit;
    
    import java.util.List;
    /**
     * 操作数据库的接口
     */
    public interface FruitMapper {
        /* 查询所有数据 */
        @Select("select fid id, fname name,price,fcount count,remark,producer from t_fruit")
        List<Fruit> findAll(RowBounds rowBounds);
    
        /* 查询总数据量 */
        @Select("select count(*) from t_fruit")
        int fruitCount();
    
        /* 新增水果库存 数据库实现了id自增策略,不用写id;字段名要和数据库一致,不用写别名 */
        @Insert("insert into t_fruit(fname,price,fcount,remark,producer) values (#{name},#{price},#{count},#{remark},#{producer})")
        int addFruit(Fruit fruit);
    
        //删除库存
        @Delete("delete from t_fruit where fid=#{id}")
        int delFruit(Integer id);
    
        //修改库存
        @Update("update t_fruit set fname=#{name}, price=#{price},fcount=#{count},remark=#{remark},producer=#{producer} where fid=#{id}")
        int updateFruit(Fruit fruit);
    
        //根据水果名称查询水果信息
        @Select("select fid id, fname name,price,fcount count,remark,producer from t_fruit where fname=#{fruitName}")
        Fruit findByName(String fruitName);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    5、业务层(Service) 编写

    到了业务层,由于本系统的业务还是比较简单的,直接调用持久层就可以了:

    package service;
    
    import pojo.Fruit;
    
    import java.util.List;
    /**
     * 业务层接口
     */
    public interface FruitService {
        /* 逻辑分页 */
        List<Fruit> fruitPages(Integer pageNum);
        /* 查询总条数 */
        int fruitCount();
    
        //新增库存
        int saveFruit(Fruit fruit);
    
        //删除库存
        int delFruit(Integer id);
    
        //修改库存
        int updateFruit(Fruit fruit);
    
        //根据水果名称查询水果信息
        Fruit findByName(String fruitName);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    业务实现类如下:

    package service.impl;
    
    import mapper.FruitMapper;
    import org.apache.ibatis.session.RowBounds;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    import pojo.Fruit;
    import service.FruitService;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    /**
     * 水果库存业务具体实现
     */
    @Service
    public class FruitServiceImpl implements FruitService {
    	//依赖注入持久层
        @Resource
        private FruitMapper fruitMapper;
    	
    	/**
         * 利用RowBounds分页查询(逻辑分页)
         * @param pageNum
         * @return
         */
        @Override
        public List<Fruit> fruitPages(Integer pageNum) {
            //分页 公式:(当前页-1)*当前页条数
            RowBounds rowBounds = new RowBounds((pageNum-1)*5,5);
            return fruitMapper.findAll(rowBounds);
        }
    
    	/**
         * 获取水果库存总数量
         * @return
         */
        @Override
        public int fruitCount() {
            return fruitMapper.fruitCount();
        }
    
        /**
         * 新增水果库存业务
         * @param fruit
         * @return
         */
        @Override
        @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
        public int saveFruit(Fruit fruit) {
            int flg = fruitMapper.addFruit(fruit);
            return flg;
        }
    
    	/**
         * 删除操作
         * @param id
         * @return
         */
        @Override
        public int delFruit(Integer id) {
            return fruitMapper.delFruit(id);
        }
    
        /**
         * 修改库存
         * @param fruit
         */
        @Override
        @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
        public int updateFruit(Fruit fruit) {
            return fruitMapper.updateFruit(fruit) ;
        }
    
        /**
         * 根据水果名称查询水果库存
         * @param fruitName 水果名称
         * @return
         */
        @Override
        public Fruit findByName(String fruitName) {
            Fruit fruit = fruitMapper.findByName(fruitName);
           return fruit;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    6、控制层(Controller) 编写

    最后就到了控制层的编写,这里是直接与前端交互的接口,具体代码如下:

    package controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    import pojo.Fruit;
    import service.FruitService;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Controller
    @RequestMapping("/fruit")
    public class FruitController {
    	//依赖注入业务层
        @Resource
        private FruitService fruitService;
    
    	/**
         * 访问首页
         * @return
         */
        @RequestMapping("/index")
        public String index(){
            return "/index";
        }
    
        /**
         * 查询水果库存列表
         * @param pageNum
         * @param model 存储到域中
         * @return
         */
        @GetMapping("/all/{pageNum}")
        public String findAll(@PathVariable(required = false) Integer pageNum, Model model){
            List<Fruit> fruitList = fruitService.fruitPages(pageNum);
            model.addAttribute("fruitList",fruitList);
            //查询总条数
            int count = fruitService.fruitCount();
            model.addAttribute("count",count);
            //页数
            model.addAttribute("pageNum",pageNum);
            System.out.println(model.getAttribute("fruitList"));
            return "food"; //指定页面
        }
    
        /**
         * 新增水果库存
         * produces = "application/json;charset=UTF-8":防止响应数据乱码
         * @return msg 响应数据
         */
        @PostMapping(value = "/addFruit", produces = "application/json;charset=UTF-8")
        @ResponseBody
        public String addFruit(Fruit fruit){
            //响应信息
            String msg = "添加水果库存成功!";
            //在添加水果库存之前查询一下水果名称是否唯一
            Fruit fruit1 = fruitService.findByName(fruit.getName());
            if (fruit1 != null){//存在
                //响应提示语给前端
                msg = "该水果名称已注册,不可复用!";
                return msg;
            }
            //调用服务层进行新增水果库存
            int flg = fruitService.saveFruit(fruit);
            if (flg < 1){
                msg = "添加水果库存失败,请联系管理员!";
            }
            return msg;
        }
    
        /**
         * 修改水果库存
         * @param fruit
         * @return msg 响应数据
         */
        @PostMapping(value = "/updateFruit", produces = "application/json;charset=UTF-8")
        @ResponseBody
        public String updateFruit(Fruit fruit){
            //响应信息
            String msg = "水果库存修改失败!";
            //传进来的库存不为空并且id不为空
            if (fruit != null && fruit.getId() != null){
                //在添加水果库存之前查询一下水果名称是否唯一
                Fruit dbFruit = fruitService.findByName(fruit.getName());
                System.out.println("传进来:"+fruit+"\n数据库中:"+dbFruit);
                //校验水果名称是否已注册但排除本身
                if (dbFruit != null && dbFruit.getId() != fruit.getId()){//存在
                    //响应提示语给前端
                    msg = "该水果名称已注册,不可复用!";
                    return msg;
                }
                //校验完毕,进行修改操作
                int flg = fruitService.updateFruit(fruit);
                if (flg >= 1)  msg = "水果库存修改成功!";
            }
            System.out.println("水果:"+fruit);
            return msg;
        }
    
        /**
         * 删除水果库存
         * @param id
         * @return
         */
        @GetMapping(value = "/delFruit", produces = "application/json;charset=UTF-8")
        @ResponseBody
        public String deleteFruit(Integer id){
            //响应信息
            String msg = "删除水果库存成功!";
            if (null == id){
                msg = "请选择待删除的库存";
                return msg;
            }
    
            //调用服务层进行删除水果库存
            int flg = fruitService.delFruit(id);
            if (flg < 1){
                msg = "删除水果库存失败,请联系管理员!";
            }
            return msg;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    到此,后端的代码就已经编写完成了,我们来看一下整体结构图:
    后端结构图

    五、前端篇

    1、页面结构HTML

    后端代码已经编写完毕了,接下来就是前端页面了,我们先把页面结构编写出来,而前端的所有代码在本项目中是存放在web\WEB-INF\pages;本系统页面一共有2个,分别是index首页和food主体页面,具体HTML页面代码如下所示~

    1.1 index页面:

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>水果库存系统title>
        <style>
            h1{
                padding: 5px 10px 8px 10px;
                background-color: blanchedalmond;
                font-family: kaiti;
                display: inline-block;
                border-radius: 5px;
                margin: 0;
            }
            h2{
                text-align: center;
                padding-top: 20px;
            }
            h2 a{
                text-decoration: none;
            }
        style>
    head>
    <body>
        <h1>水果库存系统h1>
        <h2>
            <a th:href="@{/fruit/all/1}">进入水果库存详情页>>>a>
        h2>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    1.2 food页面:

    DOCTYPE html>
    
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>水果库存title>
        
        <link rel="stylesheet" type="text/css" href="./css/food.css" th:href="@{/css/food.css}" />
    head>
    
    <body>
        <div id="div_conteiner">
            <div id="div_fruit_list">
                <table id="tbl_fruit">
                    <thead>
                        <tr>
                            <th class="w16">名称th>
                            <th class="w16">单价th>
                            <th class="w16">数量th>
                            <th class="w16">广告词th>
                            <th class="w16">产地th>
                            <th class="w16">操作th>
                        tr>
                    thead>
                    <tbody>
                        
                        <tr th:each="fruit,item:${fruitList}" th:id="${item.count}">
                            
                            <input type="hidden" name="id" th:id="|id${item.count}|" th:value="${fruit.id}">
                            <td th:text="${fruit.name}" th:class="|name${item.count}|">西瓜td>
                            <td th:text="${fruit.price}" th:class="|price${item.count}|">3td>
                            <td th:text="${fruit.count}" th:class="|count${item.count}|">60td>
                            <td th:text="${fruit.remark}" th:class="|remark${item.count}|">描述td>
                            <td th:text="${fruit.producer}" th:class="|producer${item.count}|">产地td>
                            <td>
                                <img src="./images/del.jpg" th:src="@{/images/del.jpg}" th:id="${item.count}" alt="删除" class="delImg"/>
                            td>
                        tr>
    
                        <tr th:if="${#lists.isEmpty(fruitList)}">
                            <td colspan="6">对不起,暂无数据!td>
                        tr>
                    tbody>
    
                    <tfoot>
                        <tr>
                            <td colspan="6">
                                <span>当前第 <span style="color: coral; size: 1.5rem; font-weight: bold" th:text="${pageNum}">1span>     span>
                                <a th:if="${pageNum>1}" th:href="@{/fruit/all/{pageNum}(pageNum=${pageNum}-1)}">上一页a>
                                <a th:if="${pageNum==1}" th:disabled="true">上一页a>
                                <span>  |  span>
                                <a th:href="@{/fruit/all/{pageNum}(pageNum=${pageNum}+1)}">下一页a>
                                <span>  总条数:<strong style="color: coral; size: 1.5rem;" th:text="${count}">strong>span>
                            td>
                        tr>
                    tfoot>
                table>
                <hr color="black"/>
                <div id="add_fruit_div">
                    <table id="add_fruit_tbl">
                        <tr>
                            <td>名称:td>
                            <td>
                                <input type="text" id="name" />
                            td>
                        tr>
                        <tr>
                            <td>单价:td>
                            <td>
                                <input type="text" id="price"/>
                            td>
                        tr>
                        <tr>
                            <td>数量:td>
                            <td>
                                <input type="text" id="count"/>
                            td>
                        tr>
                        <tr>
                            <td>广告词:td>
                            <td>
                                <input type="text" id="remark"/>
                            td>
                        tr>
                        <tr>
                            <td>产地:td>
                            <td>
                                <input type="text" id="producer"/>
                            td>
                        tr>
                        <th colspan="2">
                            <input type="button" value="添加" id="addOrUpdateBtn" class="addBtn"/>
                        th>
                    table>
                div>
            div>
        div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    【说明】以上都是使用了Thymeleaf模板引擎,我们再把CSS样式编写完毕,就可以访问一下页面试试效果了。

    2、页面样式CSS

    html{
        width: 100%;
        height: 100%;
    }
    body{
        margin: 0;
        padding: 0;
        background:url(../images/bg.jpg) center no-repeat;
        background-size: cover;
        
    }
    /*所有div设置*/
    div{
        position: relative;
        float: left;
    }
    
    /*页面数据主体*/
    #div_conteiner{
        width: 80%;
        height: 100%;
        margin-left: 13%;
        float: left;
        margin-top: 3%;
       
    }
    /*数据列表大盒子*/
    #div_fruit_list{
        width: 89%;
        text-align: center;
        background-color: rgb(237, 249, 255);
        border-radius: 20px;
        padding-top: 2%;
        padding-bottom: 2%;
    }
    /*搜索栏*/
    .search{
        margin-bottom: 5px;
        margin-left: 9%;
    }
    .search input{
        font-size: 1.2rem;
        padding: 3px;
        border-radius: 5px 0 0 5px;
        outline: none;
        border: lightgray solid 2px;
    
    }
    .search button{
        font-size: 1.2rem;
        border-radius: 0 5px 5px 0;
        border: lightgray solid 2px;
        padding-bottom: 3px;
        background-color: #1371c3;
        color: white;
        cursor: pointer;
        position: relative;
        right: 7px;
    }
    
    /*显示数据列表*/
    #tbl_fruit{
        width: 80%;
        text-align: center;
        line-height:45px;
        margin-left: 9%;
        border-radius: 20px;
    }
    #tbl_fruit,#tbl_fruit tr,#tbl_fruit th,#tbl_fruit td{
        border: 1px solid gray;
        border-collapse: collapse;
    }
    .w16{
        width: 16%;
    }
    .delImg{
        width: 30px;
        height: 30px;
        vertical-align: middle; /* 图片垂直居中 */
        cursor: pointer;
    }
    thead{
      font-size: 1.3rem;  
    }
    
    #add_fruit_div{
        width: 40%;
        margin-left: 30%;
    }
    #add_fruit_tbl{
        width: 80%;
        margin-top: 5px;
        margin-left: 5%;
        border-collapse: collapse;
    }
    #add_fruit_tbl,#add_fruit_tbl tr,#add_fruit_tbl th,#add_fruit_tbl td{
        border: 1px solid lightgray;
        text-align: center;
    }
    
    /*添加和修改*/
    #add_fruit_tbl input{
        outline: none;
    }
    #add_fruit_tbl td input[type='text']{
        width: 90%;
        padding: 4px;
    }
    /*添加修改按钮样式*/
    .addBtn{
        font-size: 1.2rem;
        padding: 3px 16px;
    }
    
    /*a链接禁用*/
    a[disabled] {
        pointer-events: none;
        cursor: default;
        text-decoration: none;
        color: #999;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    到此我们可以查看一下页面效果:
    index页面
    主页面
    以上就是编码到目前为止的页面效果了;数据的展示是我已经在数据库中添加了一些数据,然后由于我们使用Thymeleaf遍历后端传来的数据,所以有数据显示,也由此查询分页功能也就完成了。

    3、JavaScript脚本编写

    接下来就到最后一步了,那就是把剩下的新增、修改和删除功能利用Ajax技术与后端联调就可以了。不过在联调之前,我们在本系统的数据展示模块利用js写点附属功能上去,需求是这样的:**当鼠标悬浮到对应的的行的时候,会更换颜色,当鼠标移除的时候会变回原本的颜色。**具体实现如下所示:

    //当鼠标悬浮时,显示背景颜色
    function showBGColor(e) {
        //获取事件源  event:当前发生的事件 tagName:获取当前的元素
        // alert(event.srcElement.tagName)
        // alert(window.event.srcElement.tagName);
        //判断是否存在该元素
        if (window.event && window.event && window.event.srcElement.tagName == "TD") {
            var td = window.event.srcElement;
            var tr = td.parentElement;
            //设置样式
            tr.style.backgroundColor = "lightblue";
            //获取tr中所有单元格
            var tds = tr.cells;
            for (var i = 0; i < tds.length; i++) {
                tds[i].style.color = "white";
            }
        }
    }
    
    //鼠标移除时执行
    function cleanBGColor() {
        if (window.event && window.event && window.event.srcElement.tagName == "TD") {
            var td = window.event.srcElement;
            var tr = td.parentElement;
            //设置样式
            tr.style.backgroundColor = " rgb(237, 249, 255)";
            //获取tr中所有单元格
            var tds = tr.cells;
            for (var i = 0; i < tds.length; i++) {
                tds[i].style.color = "black";
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    然后我们在food.html页面引入

    	
    	<script type="text/javascript" src="./js/food.js" th:src="@{/js/food.js}" >script>
    	
        <script type="text/javascript" src="js/jquery-3.3.1.min.js" th:src="@{/js/jquery-3.3.1.min.js}">script>
    
    • 1
    • 2
    • 3
    • 4

    然后我们在到html对应的标签中添加鼠标悬浮和移除事件

    	
     	<tr th:each="fruit,item:${fruitList}" th:id="${item.count}" onmouseover="showBGColor()" onmouseout ="cleanBGColor()">
     	tr>
    
    • 1
    • 2
    • 3

    我们来看一下功能实现:

    悬浮
    鼠标悬浮的时候,出现背景颜色~~

    移除
    鼠标移除,变回原本的颜色,功能实现OK。

    3.1 新增和修改功能

    废话不多说,直接上代码:

    //当页面加载完成后执行
    window.onload = function () {
        addFruit();
    }
    
    //点击添加按钮时进行数据新增操作
    function addFruit(){
        $("#addOrUpdateBtn").click(function(){
            if ($("#addOrUpdateBtn").val() == '添加'){
                //校验
                if(!check())
                    return false;
                $.ajax({
                    url: "/fruit/addFruit",
                    type: "post",
                    data: { //前端携带的数据
                        name: $("#name").val(),
                        price: $("#price").val(),
                        count: $("#count").val(),
                        remark: $("#remark").val(),
                        producer: $("#producer").val()
                    },
                    dataType:'text', //后端是String返回,所以为文本形式表示json格式
                    success:function (data){
                        //响应数据
                        alert(data);
                        //页面刷新
                        location.reload();
                    }
                });
            }
    
        });
    }
    
    //在发起请求之前进行数据校验
    function check(){
        if ($("#name").val() == ''){
            alert("水果名称不能为空!");
            return false;
        }
        if ($("#price").val() == ''){
            alert("水果单价不能为空!");
            return false;
        }
        if ($("#count").val() == ''){
            alert("水果数量不能为空!");
            return false;
        }
        return true; //校验通过
    }
    
    //点击对应水果库存进行具体操作 参数为:id值
    function showData(id){
        switch (id){
            case '1':
                //获取水果id值
                let fid1 = $("#id"+id).val();
                //调用修改水果库存函数
                updateFruit(id,fid1);
                break;
            case '2':
                //获取水果id值
                let fid2 = $("#id"+id).val();
                updateFruit(id,fid2);
                break;
            case '3':
                //获取水果id值
                let fid3 = $("#id"+id).val();
                updateFruit(id,fid3);
                break;
            case '4':
                //获取水果id值
                let fid4 = $("#id"+id).val();
                updateFruit(id,fid4);
                break;
            case '5':
                //获取水果id值
                let fid5 = $("#id"+id).val();
                updateFruit(id,fid5);
                break;
        }
    }
    
    //修改水果库存 id:行id fid:水果id
    function updateFruit(id,fid){
        //获取水果库存各属性值
        $("#name").val($('.name'+id).text());
        $("#price").val($('.price'+id).text());
        $("#count").val($('.count'+id).text());
        $("#remark").val($('.remark'+id).text());
        $("#producer").val($('.producer'+id).text());
        //把‘添加’按钮值改为‘修改’
        $("#addOrUpdateBtn").val("修改");
    
        //点击修改按钮进行相应操作
        $("#addOrUpdateBtn").click(function (){
            if ($("#addOrUpdateBtn").val() == "修改"){
                //参数校验
                if(!check()){
                    return false;
                }
                //发起ajax请求
                $.ajax({
                    url: "/fruit/updateFruit/",
                    type: "post",
                    data: { //前端携带的数据
                        id: fid,
                        name: $("#name").val(),
                        price: $("#price").val(),
                        count: $("#count").val(),
                        remark: $("#remark").val(),
                        producer: $("#producer").val()
                    },
                    dataType:'text', //后端是String返回,所以为文本形式表示json格式
                    success:function (data){
                        //响应数据
                        alert(data);
                        //页面刷新
                        location.reload();
                    }
                });
            }
            return false;
            })
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    最后绑定点击事件就可以了

    
    <tr th:each="fruit,item:${fruitList}" th:id="${item.count}" onclick="showData(this.id)">tr>
    
    • 1
    • 2

    我们来看一下功能效果:
    add

    addOK

    addYse

    updateShow
    update
    updateOK
    由此可见,新增和修改功能都已经实现了。

    3.2 删除功能

    代码如下:

    //点击删除小图标执行删除数据的函数 num:html绑定事件中的参数获取
    function delFruit(num) {
        //用户提示框
        let result = confirm("确定要删除该记录吗?");
        if (result){
            //确定,执行删除操作
            $.ajax({
                url: "/fruit/delFruit",
                type: "get",
                data: { //前端携带的数据
                    id: $("#id"+num).val(),
                },
                dataType:'text', //后端是String返回,所以为文本形式表示json格式
                success:function (data){
                    //响应数据
                    alert(data);
                    //页面刷新
                    location.reload();
                }
            });
        }else {
            // 用户点击取消,则返回false,不执行任何操作
            return false;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    绑定点击事件,进行删除操作

    	<td>
    		
            <img src="./images/del.jpg" th:src="@{/images/del.jpg}" th:id="${item.count}" onclick="delFruit(this.id)" alt="删除" class="delImg"/>
        td>
    
    • 1
    • 2
    • 3
    • 4

    然后我们看效果即可:
    delete
    点击确定删除会出现提示语:
    deleteOK
    删除成功!!!
    deleteYes
    查询数据列表可以知道test02数据已经被删除成功!!!

    六、总结

        至此,本系统的功能实现完毕了。本系统是使用了后端SSM框架,模板引擎Thymeleaf;前端使用了HTML+CSS+JQuery技术。另外本人技术有限,可能在本篇内容中有不足之地,各方道友可私聊畅谈一二~~
        最后关于本系统使用到的静态资源可以可以使用自己的,也可以从源码中获取。本系统的源码已上传到码云。链接为:https://gitee.com/originnan/fruit

  • 相关阅读:
    Mybatis的介绍和基本使用
    虚拟化+Docker基本管理
    如何用个人电脑搭建一台本地服务器,并部署项目到服务器详细教程(Ubuntu镜像)
    [ESP32 IDF+Vscode]OLED多级菜单显示(摇杆控制)
    react+ts实战之 @reduxjs/toolkit
    场景应用:键盘敲入字母a时,期间发生了什么?
    【OpenCV】-边缘检测汇总示例
    将音频格式从flac转到wav的两种方法
    玄机科技闪耀中国国际动漫节,携手百度共绘 AI 国漫新篇章
    基于OpenVINO 2022.1 POT API实现YOLOv5模型INT8量化
  • 原文地址:https://blog.csdn.net/weixin_54679968/article/details/132570085