合川建网站,有哪些平台可以发布推广信息,tag 网站备案,苏州展示型网站建设不为失败找理由#xff0c;只为成功找方法。所有的不甘#xff0c;因为还心存梦想#xff0c;所以在你放弃之前#xff0c;好好拼一把#xff0c;只怕心老#xff0c;不怕路长。 文章目录 一、前言二、系统架构与需求分析1、技术栈1.1 后端1.2 前端 2、需求分析 三、设计… 不为失败找理由只为成功找方法。所有的不甘因为还心存梦想所以在你放弃之前好好拼一把只怕心老不怕路长。 文章目录 一、前言二、系统架构与需求分析1、技术栈1.1 后端1.2 前端 2、需求分析 三、设计数据库四、后端篇1、环境搭建2、SSM整合(配置文件编写)2.1 database.properties文件编写2.2 mybatis-config.xml编写2.3 spring-dao.xml编写2.4 spring-service.xml编写2.5 spring-mvc.xml编写2.6 applicationContext.xml编写 3、web.xml文件配置(重点)4、持久层(Mapper) 编写5、业务层(Service) 编写6、控制层(Controller) 编写 五、前端篇1、页面结构HTML1.1 index页面1.2 food页面 2、页面样式CSS3、JavaScript脚本编写3.1 新增和修改功能3.2 删除功能  六、总结 一、前言 
本系统是一个简易版的水果库存系统在前面的文章里面也有写过 水果库存基础版 和水果库存进阶版这两个版本的区别是基础版是使用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)
) ENGINEInnoDB DEFAULT CHARSETutf8;通过以上的SQL语句就可以创建一个数据库和数据表现在有了数据表那么接下来就要开始从后端到前端的开发了。我们先从后端开始 四、后端篇 1、环境搭建 后端的任何功能的开始都必须有一个环境所以我们先来搭建一个SSM环境出来。本系统IDE使用IDEA进行开发而且是基于maven的具体搭建步骤如下   以上步骤就已经创建了一个基础maven项目。接下来要配置一下maven  由于我们本系统的页面是网页的形式所以我们还需要在maven上添加web模块具体步骤如下  到此本系统的Web项目就创建完成了项目结构如下所示 项目创建完毕之后那么就该导入依赖了和我们以前导入Jar包是一个意思。之前是我们自己导入每一个Jar包但是有了maven之后那么我们只要导入对应的坐标依赖就行了至于Jar包maven会帮我们下载下来。依赖导入是在pom.xml文件中进行编写本系统使用到的依赖有如下 dependencies!-- spring --dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.3.20/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.3.20/version/dependency!-- aop与事务 --dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion5.3.20/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.3.20/version/dependency!-- mysql驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.22/version/dependency!-- mybatis --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion3.5.7/version/dependency!-- mybatis与spring整合 版本mybatis3.x以上spring5.x以上使用2.x --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion2.0.6/version/dependency!-- 模板引擎Thymeleaf --dependencygroupIdorg.thymeleaf/groupIdartifactIdthymeleaf-spring5/artifactIdversion3.0.15.RELEASE/version/dependency/dependencies!-- 静态资源导出问题 --buildresourcesresourcedirectorysrc/main/java/directoryincludesinclude**/*.properties/includeinclude**/*.xml/include/includesfilteringfalse/filtering/resourceresourcedirectorysrc/main/resources/directoryincludesinclude**/*.properties/includeinclude**/*.xml/include/includesfilteringfalse/filtering/resource/resources/build到此本项目的构建已经初步完成了但是到真正编写功能模块还得配置几个文件才可以项目有些基础的小伙伴已经知道接下来要做的步骤了那就是整合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.drivercom.mysql.cj.jdbc.Driver
# 如果数据库MySQL8以上需要在后面设置时区 serverTimezoneUTC
jdbc.urljdbc:mysql://localhost:3306/fruitdb?useSSLtrueuseUnicodetruecharacterEncodingutf8serverTimezoneUTC
# 自己本地数据库账号 和密码
jdbc.usernameroot
jdbc.passwordroot2.2 mybatis-config.xml编写 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configuration!-- 配置输出日志logging --settingssetting namelogImpl valueSTDOUT_LOGGING//settings!-- 配置数据源但和spring整合之后所以让spring去处理 --!-- 给实体类起别名 --typeAliasespackage namepojo//typeAliases!-- mapper映射注解开发扫描包交给spring --
/configuration2.3 spring-dao.xml编写 ?xml version1.0 encodingUTF-8 ?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd!-- 1、关联数据库配置文件 即database.properties --context:property-placeholder locationclasspath:database.properties/!-- 2、配置数据源 这里的数据源使用Spring的没有使用第三方池化技术--bean iddataSource classorg.springframework.jdbc.datasource.DriverManagerDataSourceproperty namedriverClassName value${jdbc.driver}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}//bean!-- 3、sqlSessionFactory --bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/!-- 绑定Mybatis的配置文件 --property nameconfigLocation valueclasspath:mybatis-config.xml//bean!-- 4、配置dao接口扫描包动态的实现了DAO接口可以注入到Spring容器中 --bean classorg.mybatis.spring.mapper.MapperScannerConfigurer!-- 注入sqlSessionFactory --property namesqlSessionFactoryBeanName valuesqlSessionFactory/!-- 要扫描的dao包 --property namebasePackage valuemapper//bean
/beans2.4 spring-service.xml编写 ?xml version1.0 encodingUTF-8 ?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd!-- 扫描service下的包 进行注解开发 --context:component-scan base-packageservice/!-- 事务使用注解式 --
/beans2.5 spring-mvc.xml编写 ?xml version1.0 encodingUTF-8 ?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:mvchttp://www.springframework.org/schema/mvcxmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://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!-- 1、注解驱动 --mvc:annotation-driven/!-- 2、静态资源过滤 --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//!-- 3、扫描包controller --context:component-scan base-packagecontroller/!-- 4、视图解析器 本系统使用Thymeleaf --bean idtemplateResolver classorg.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver!-- 前缀 --property nameprefix value/WEB-INF/pages//property!-- 后缀 --property namesuffix value.html/property!-- 指定编码 --property namecharacterEncoding valueutf-8/property!-- 是否开启缓存 --property namecacheable valuefalse/property!-- 模板的类型 --property nametemplateMode valueHTML5/property/bean!-- 配置模板引擎 --bean idtemplateEngine classorg.thymeleaf.spring5.SpringTemplateEngineproperty nametemplateResolver reftemplateResolver/property/bean!-- 配置模板视图 --bean idviewResolver classorg.thymeleaf.spring5.view.ThymeleafViewResolverproperty namecharacterEncoding valueutf-8/propertyproperty nametemplateEngine reftemplateEngine/property/bean
/beans2.6 applicationContext.xml编写 ?xml version1.0 encodingUTF-8 ?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd!-- 导入dao、service、mvc配置 --import resourceclasspath:spring-dao.xml/import resourceclasspath:spring-service.xml/import resourceclasspath:spring-mvc.xml/
/beans本文件配置的目的是为了把三个文件整合起来变成一个文件到后面启动项目的时候利用Tomcat初始化配置把该文件作为接口加载即可。 3、web.xml文件配置(重点) ☆☆☆本文件特别重要如果本文件没有配置那么当访问页面的时候会出现404。原因是本配置是暴露给浏览器的。本文件是在WEB-INF目录下具体配置如下所示 ?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0!-- DispatchServlet 前端控制器配置 --servletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-classinit-param!-- 加载所有的配置文件 applicationContext.xml里加载了全部文件 --param-namecontextConfigLocation/param-nameparam-valueclasspath:applicationContext.xml/param-value/init-param!-- 当值为0或者大于0时表示容器在应用启动时就加载这个servlet;反则需要时加载 --load-on-startup1/load-on-startup/servlet!-- 映射路径 --servlet-mappingservlet-namespringmvc/servlet-nameurl-pattern//url-pattern/servlet-mapping!-- 乱码过滤 --filterfilter-nameencodingFilter/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueutf-8/param-value/init-param/filter!-- 过滤路径/* 全部过滤 --filter-mappingfilter-nameencodingFilter/filter-nameurl-pattern/*/url-pattern/filter-mapping!-- Session --session-configsession-timeout15/session-timeout/session-config
/web-app到此本系统的所有配置就已经完毕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、settingpublic 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;}Overridepublic String toString() {return Fruit{ id  id , name  name  \ , price  price , count  count , remark  remark  \ , producer  producer  \ };}
} 数据映射已经编写完成接下来就是功能实现了持久层代码如下 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)ListFruit 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);
} 5、业务层(Service) 编写 到了业务层由于本系统的业务还是比较简单的直接调用持久层就可以了 package service;import pojo.Fruit;import java.util.List;
/*** 业务层接口*/
public interface FruitService {/* 逻辑分页 */ListFruit fruitPages(Integer pageNum);/* 查询总条数 */int fruitCount();//新增库存int saveFruit(Fruit fruit);//删除库存int delFruit(Integer id);//修改库存int updateFruit(Fruit fruit);//根据水果名称查询水果信息Fruit findByName(String fruitName);
} 业务实现类如下 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 {//依赖注入持久层Resourceprivate FruitMapper fruitMapper;/*** 利用RowBounds分页查询逻辑分页* param pageNum* return*/Overridepublic ListFruit fruitPages(Integer pageNum) {//分页 公式(当前页-1)*当前页条数RowBounds rowBounds  new RowBounds((pageNum-1)*5,5);return fruitMapper.findAll(rowBounds);}/*** 获取水果库存总数量* return*/Overridepublic int fruitCount() {return fruitMapper.fruitCount();}/*** 新增水果库存业务* param fruit* return*/OverrideTransactional(propagation  Propagation.REQUIRED, rollbackFor  Exception.class)public int saveFruit(Fruit fruit) {int flg  fruitMapper.addFruit(fruit);return flg;}/*** 删除操作* param id* return*/Overridepublic int delFruit(Integer id) {return fruitMapper.delFruit(id);}/*** 修改库存* param fruit*/OverrideTransactional(propagation  Propagation.REQUIRED,rollbackFor  Exception.class)public int updateFruit(Fruit fruit) {return fruitMapper.updateFruit(fruit) ;}/*** 根据水果名称查询水果库存* param fruitName 水果名称* return*/Overridepublic Fruit findByName(String fruitName) {Fruit fruit  fruitMapper.findByName(fruitName);return fruit;}
} 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 {//依赖注入业务层Resourceprivate 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){ListFruit 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;charsetUTF-8防止响应数据乱码* return msg 响应数据*/PostMapping(value  /addFruit, produces  application/json;charsetUTF-8)ResponseBodypublic 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;charsetUTF-8)ResponseBodypublic 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;charsetUTF-8)ResponseBodypublic String deleteFruit(Integer id){//响应信息String msg  删除水果库存成功;if (null  id){msg  请选择待删除的库存;return msg;}//调用服务层进行删除水果库存int flg  fruitService.delFruit(id);if (flg  1){msg  删除水果库存失败请联系管理员;}return msg;}
} 到此后端的代码就已经编写完成了我们来看一下整体结构图  五、前端篇 1、页面结构HTML 后端代码已经编写完毕了接下来就是前端页面了我们先把页面结构编写出来而前端的所有代码在本项目中是存放在web\WEB-INF\pages本系统页面一共有2个分别是index首页和food主体页面具体HTML页面代码如下所示~ 1.1 index页面 !DOCTYPE html
html langen
headmeta charsetUTF-8title水果库存系统/titlestyleh1{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
bodyh1水果库存系统/h1h2a th:href{/fruit/all/1}进入水果库存详情页/a/h2
/body
/html1.2 food页面 !DOCTYPE html
!-- xmlns:thhttp://www.thymeleaf.org Thymeleaf的声明有语法提示th开头的都是Thymeleaf语法 --
html langen xmlns:thhttp://www.thymeleaf.orgheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title水果库存/title!-- 路径前面要加/ 当前目录 --link relstylesheet typetext/css href./css/food.css th:href{/css/food.css} /
/headbodydiv iddiv_conteinerdiv iddiv_fruit_listtable idtbl_fruittheadtrth classw16名称/thth classw16单价/thth classw16数量/thth classw16广告词/thth classw16产地/thth classw16操作/th/tr/theadtbody!-- 从服务器中获取数据 --tr th:eachfruit,item:${fruitList} th:id${item.count}!-- 隐藏域 存放水果编号 --input typehidden nameid th:id|id${item.count}| th:value${fruit.id}td th:text${fruit.name} th:class|name${item.count}|西瓜/tdtd th:text${fruit.price} th:class|price${item.count}|3/tdtd th:text${fruit.count} th:class|count${item.count}|60/tdtd th:text${fruit.remark} th:class|remark${item.count}|描述/tdtd th:text${fruit.producer} th:class|producer${item.count}|产地/tdtdimg src./images/del.jpg th:src{/images/del.jpg} th:id${item.count} alt删除 classdelImg//td/trtr th:if${#lists.isEmpty(fruitList)}td colspan6对不起暂无数据/td/tr/tbodytfoottrtd colspan6span当前第nbsp;span stylecolor: coral; size: 1.5rem; font-weight: bold th:text${pageNum}1/spannbsp;页nbsp;nbsp;nbsp;nbsp;/spana th:if${pageNum1} th:href{/fruit/all/{pageNum}(pageNum${pageNum}-1)}上一页/aa th:if${pageNum1} th:disabledtrue上一页/aspannbsp;nbsp;|nbsp;nbsp;/spana th:href{/fruit/all/{pageNum}(pageNum${pageNum}1)}下一页/aspannbsp;nbsp;总条数strong stylecolor: coral; size: 1.5rem; th:text${count}/strong/span/td/tr/tfoot/tablehr colorblack/div idadd_fruit_divtable idadd_fruit_tbltrtd名称/tdtdinput typetext idname //td/trtrtd单价/tdtdinput typetext idprice//td/trtrtd数量/tdtdinput typetext idcount//td/trtrtd广告词/tdtdinput typetext idremark//td/trtrtd产地/tdtdinput typetext idproducer//td/trth colspan2input typebutton value添加 idaddOrUpdateBtn classaddBtn//th/table/div/div/div
/body
/html【说明】以上都是使用了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[typetext]{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;
} 到此我们可以查看一下页面效果   以上就是编码到目前为止的页面效果了数据的展示是我已经在数据库中添加了一些数据然后由于我们使用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;}}
}然后我们在food.html页面引入 	!-- food.js 即上面代码存储的文件 --script typetext/javascript src./js/food.js th:src{/js/food.js} /script!-- 后续功能实现要使用到Ajax所以引入jQuery库 --script typetext/javascript srcjs/jquery-3.3.1.min.js th:src{/js/jquery-3.3.1.min.js}/script然后我们在到html对应的标签中添加鼠标悬浮和移除事件 	!-- onmouseover鼠标悬浮显示背景颜色onmouseout鼠标移除清除背景颜色 --tr th:eachfruit,item:${fruitList} th:id${item.count} onmouseovershowBGColor() onmouseout cleanBGColor()/tr我们来看一下功能实现  鼠标悬浮的时候出现背景颜色~~  鼠标移除变回原本的颜色功能实现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  $(#idid).val();//调用修改水果库存函数updateFruit(id,fid1);break;case 2://获取水果id值let fid2  $(#idid).val();updateFruit(id,fid2);break;case 3://获取水果id值let fid3  $(#idid).val();updateFruit(id,fid3);break;case 4://获取水果id值let fid4  $(#idid).val();updateFruit(id,fid4);break;case 5://获取水果id值let fid5  $(#idid).val();updateFruit(id,fid5);break;}
}//修改水果库存 id行id fid水果id
function updateFruit(id,fid){//获取水果库存各属性值$(#name).val($(.nameid).text());$(#price).val($(.priceid).text());$(#count).val($(.countid).text());$(#remark).val($(.remarkid).text());$(#producer).val($(.producerid).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;})
} 最后绑定点击事件就可以了 !-- 绑定点击事件函数 showData(this.id)把id值传参这里就可以实现数据显示了 --
tr th:eachfruit,item:${fruitList} th:id${item.count} onclickshowData(this.id)/tr我们来看一下功能效果       由此可见新增和修改功能都已经实现了。 3.2 删除功能 代码如下 //点击删除小图标执行删除数据的函数 numhtml绑定事件中的参数获取
function delFruit(num) {//用户提示框let result  confirm(确定要删除该记录吗);if (result){//确定执行删除操作$.ajax({url: /fruit/delFruit,type: get,data: { //前端携带的数据id: $(#idnum).val(),},dataType:text, //后端是String返回所以为文本形式表示json格式success:function (data){//响应数据alert(data);//页面刷新location.reload();}});}else {// 用户点击取消则返回false不执行任何操作return false;}
} 绑定点击事件,进行删除操作 	td!-- οnclickdelFruit(this.id)传入的参数是id值 --img src./images/del.jpg th:src{/images/del.jpg} th:id${item.count} onclickdelFruit(this.id) alt删除 classdelImg//td然后我们看效果即可  点击确定删除会出现提示语  删除成功  查询数据列表可以知道test02数据已经被删除成功 六、总结     至此本系统的功能实现完毕了。本系统是使用了后端SSM框架模板引擎Thymeleaf前端使用了HTMLCSSJQuery技术。另外本人技术有限可能在本篇内容中有不足之地各方道友可私聊畅谈一二~~     最后关于本系统使用到的静态资源可以可以使用自己的也可以从源码中获取。本系统的源码已上传到码云。链接为https://gitee.com/originnan/fruit