前端页面使用Thymeleaf模板(跟JSP页面类似),但是它的功能比JSP强大并且用法简洁
在登录页面输入用户名和密码,然后点击“登录”按钮,跳转到“后台管理系统”的主页
在父工程的POM文件中新添加前端框架的依赖
<webjars.bootstrap.version>3.3.7webjars.bootstrap.version>
<webjars.jquery.version>3.3.1webjars.jquery.version>
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>bootstrapartifactId>
<version>${webjars.bootstrap.version}version>
dependency>
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>jqueryartifactId>
<version>${webjars.jquery.version}version>
dependency>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logbackgroupId>
<artifactId>*artifactId>
exclusion>
<exclusion>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>*artifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4jartifactId>
<version>1.3.8.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.junit.vintagegroupId>
<artifactId>junit-vintage-engineartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
dependency>
<dependency>
<groupId>org.junit.platformgroupId>
<artifactId>junit-platform-launcherartifactId>
dependency>
<dependency>
<groupId>org.junit.platformgroupId>
<artifactId>junit-platform-commonsartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>bootstrapartifactId>
dependency>
<dependency>
<groupId>org.webjarsgroupId>
<artifactId>jqueryartifactId>
dependency>
dependencies>
在resource
目录下定义application.yml
文件。如图所示:
# 配置服务器端口号
server:
port: 8091
# 数据库连接和Druid连接池配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/minzu?useUnicode=true&characterEncoding=UTF8&useSSL=false
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid:
min-idle: 5
max-active: 10
max-wait: 3000
# 配置Thymeleaf模板,该模板的后缀为.html,后缀为Classpath下面的/templates/water/
thymeleaf:
suffix: .html
prefix: classpath:/templates/water/
# 禁用Thymeleaf缓存
cache: false
# MyBatis-Plus配置
mybatis-plus:
configuration:
# 实体类属性支持驼峰映射
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 主键自动增长
global-config:
db-config:
id-type: auto
在resource
目录下定义log4j.properties
文件。如图所示:
# 将日志级别为DEBUG的日志信息输出到file(文件)和console(控制台)这两个目的地
log4j.rootLogger=INFO, file, console
# 文件输出的相关设置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/caojie.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n
#控制台输出的相关设置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss SSS} %5p %c{1}:%L - %m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
entities包下面放置实体类
mapper包下面放置Mapper接口,主要用来在实体类的属性和数据库表字段之间做映射,封装了数据库的增删改查操作
service包定义了业务逻辑
controller包定义了控制器,专门用于处理浏览器发起的请求
如图所示:
package com.shouyi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* TODO
*
* @author caojie
* @version 1.0
*/
@SpringBootApplication
@MapperScan("com.shouyi.mapper")
public class ShouyiSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(ShouyiSpringBootApplication.class,args);
}
}
package com.shouyi.entities;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* TODO
* @author caojie
* @version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_account")
public class Account {
private Integer aid;
private String userName;
private String userPwd;
private String userEmail;
private String userMobile;
}
package com.shouyi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.shouyi.entities.Account;
import org.springframework.stereotype.Repository;
/**
* TODO
* AccountMapper是一个映射器接口,它在数据库表的字段和Java实体类属性之间做映射
* @author caojie
* @version 1.0
*/
@Repository
public interface AccountMapper extends BaseMapper<Account> {
}
package com.shouyi.service;
import com.shouyi.entities.Account;
/**
* TODO: 用户登录业务逻辑接口
*
* @author caojie
* @version 1.0
*/
public interface AccountService {
/**
* 用户登录
* 步骤:
* 1 根据用户名查询对应的账户信息
* 2 判断账户是否为空,如果为空登录失败,返回false
* 3 如果账户非空,对用户输入的密码进行MD5加密
* 4 比较数据库的密码和加密的密码是否相等
* 5 如果相等,登录成功返回true,否则,登录失败返回false
* @param userName 用户名
* @param userPwd 密码
* @return true登录成功,false登录失败
*/
boolean login(String userName,String userPwd);
}
package com.shouyi.service.impl;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shouyi.entities.Account;
import com.shouyi.mapper.AccountMapper;
import com.shouyi.service.AccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* TODO:登录业务逻辑实现类
* 被@Service注解修饰的类,是业务逻辑接口的实现类
* @author caojie
* @version 1.0
*/
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {
/**
自动装配AccountMapper对象
*/
@Autowired
private AccountMapper accountMapper;
/**
* 用户登录
* 步骤:
* 1 根据用户名查询对应的账户信息
* 2 判断账户是否为空,如果为空登录失败,返回false
* 3 如果账户非空,对用户输入的密码进行MD5加密
* 4 比较数据库的密码和加密的密码是否相等
* 5 如果相等,登录成功返回true,否则,登录失败返回false
*
* @param
* @return true登录成功,false登录失败
*/
@Override
public boolean login(String userName,String userPwd) {
log.info("userName = "+userName+" userPwd = "+userPwd);
QueryWrapper<Account> qw = new QueryWrapper<>();
qw.eq("user_name",userName);
// 根据用户名查询对应的账号信息
Account account = accountMapper.selectOne(qw);
if (null == account) {
return false;
}
// 对表单输入的密码进行MD5加密
String encodePwd = DigestUtil.md5Hex(userPwd);
// 比较数据库密码和加密的密码是否相等,条件成立:登录成功,否则登录失败
if (Objects.equals(encodePwd,encodePwd)) {
return true;
} else {
return false;
}
}
}
package com.shouyi.controller;
import com.shouyi.service.AccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* TODO: 用户登录对应的控制器,用来处理用户登录的业务逻辑
* @author caojie
* @version 1.0
* @date 2021/10/21 11:15
*/
@Controller
@Slf4j
public class AccountController {
@Autowired
private AccountService accountService;
/**
* 处理浏览器用户登录的请求
* 步骤:
* 1 调用业务逻辑层对象AccountService的login方法判断用户名密码是否正确
* 2 如果用户明密码正确,表示登录成功,跳转到送水公司后台管理系统主页
* 3 否则,给出提示,不进行跳转
* @param userName 表单采集的用户名
* @param userPwd 表单采集的密码
* @return 登录成功,跳转到送水公司后台管理系统主页,登录失败给出提示,重新回到登录页面
*/
@RequestMapping(value="/login",method = RequestMethod.POST)
public String loginAccount(String userName, String userPwd, Model model) {
boolean result = accountService.login(userName, userPwd);
if (result) {
return "waterMainMenu";
} else {
model.addAttribute("loginFail","用户名密码错误");
return "index";
}
}
}
项目所有静态资源都放在resource目录下,css存放层叠样式表,fonts存放页面字体信息,images存放项目用到的图片。
项目所有静态页面都放在resource目录下
1 index.html 登录页面
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Logintitle>
<meta charset="utf-8">
<link th:href="@{/css/style2.css}" rel='stylesheet' type='text/css' />
head>
<body>
<div class="main">
<div class="login-form">
<h1>用户登录h1>
<div class="head">
<img src="../../images/user.png" alt=""/>
div>
<form th:action="@{/login}" th:method="post">
<input type="text" class="text" name="userName" required >
<input type="password" name="userPwd" required>
<div class="submit">
<input type="submit" name="submit" value="登录" >
div>
<p><a href="#">Forgot Password ?a>p>
<p style="color:red" th:if="${not #strings.isEmpty(loginFail)}" th:text="${loginFail}">p>
form>
div>
<div class="copy-right">
<p>Copyright © 2014.Company name All rights reserved.<a target="_blank" href="http://sc.chinaz.com/moban/">网页模板a>p>
div>
div>
<div style="display:none"><script src='http://v7.cnzz.com/stat.php?id=155540&web_id=155540' language='JavaScript' charset='gb2312'>script>div>
body>
html>
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
head>
<body>
<div id="viewport">
<div id="sidebar">
<header>
<a href="#">公司后台管理a>
header>
<ul class="nav">
<li>
<a>
<i class="zmdi zmdi-view-dashboard">i> 客户管理
a>
li>
<li>
<a>
<i class="zmdi zmdi-link">i> 送水工管理
a>
li>
<li>
<a>
<i class="zmdi zmdi-widgets">i> 送水历史管理
a>
li>
<li>
<a>
<i class="zmdi zmdi-widgets">i> 计算工资
a>
li>
<li>
<a>
<i class="zmdi zmdi-widgets">i> 统计送水数量
a>
li>
<li>
<a>
<i class="zmdi zmdi-widgets">i> 修改密码
a>
li>
ul>
div>
<div id="content">
<nav class="navbar navbar-default">
<div class="container-fluid" >
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#"><i class="zmdi zmdi-notifications text-danger">i>
a>
li>
<li><a href="#">测试用户123a>li>
ul>
div>
nav>
<div class="container-fluid">
div>
div>
div>
body>
html>
http://localhost:8091/
点击“客户管理”,显示客户信息列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dQuH7zSG-1650766048455)(assets/1634816951797.png)]
package com.shouyi.entities;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* TODO: 客户实体类
* @author caojie
* @version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_customer")
public class Customer {
/**
* 客户编号
*/
private Integer cid;
/**
* 客户名称
*/
private String custName;
/**
* 客户地址
*/
private String custAddress;
/**
* 客户联系方式
*/
private String custMobile;
/**
* 水票数量
*/
private String custTicket;
}
package com.shouyi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.shouyi.entities.Customer;
import org.springframework.stereotype.Repository;
/**
* TODO:客户管理的映射器,在客户表和实体类之间做映射
* @author caojie
* @version 1.0
*/
@Repository
public interface CustomerMapper extends BaseMapper<Customer> {
}
package com.shouyi.service;
import com.shouyi.entities.Customer;
import java.util.List;
/**
* TODO: 客户管理
* @author caojie
* @version 1.0
*/
public interface CustomerService {
/**
* 返回所有客户信息
* @return 客户列表
*/
List<Customer> listCustomer();
}
package com.shouyi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shouyi.entities.Customer;
import com.shouyi.mapper.CustomerMapper;
import com.shouyi.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* TODO:客户管理接口实现类
*
* @author caojie
* @version 1.0
*/
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerMapper customerMapper;
/**
* 返回所有客户信息
*
* @return 客户列表
*/
@Override
public List<Customer> listCustomer() {
return customerMapper.selectList(null);
}
}
package com.minzu.controller;
import com.minzu.entities.Customer;
import com.minzu.service.CustomerService;
import com.minzu.service.impl.CustomerServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* TODO: 客户管理的控制器,处理客户管理所有的请求
*
* @author caojie
* @version 1.0
* @date 2021/10/22 8:29
*/
@Controller
@RequestMapping("/cust")
@Slf4j
public class CustomerController {
/**
* 控制器依赖业务逻辑,按照类型自动装配CustomerService对象
*/
@Autowired
private CustomerService customerService ;
/**
* 用户点击"客户管理"超链接按钮,显示所有的客户信息
* 步骤:
* 1 调用CustomerService对象的listCustomer方法查询所有的客户信息
* 2 将客户信息渲染到客户列表页面
* 3 跳转到客户列表页面
* @param model 在前端和后端之间传递数据的对象
* @return 客户列表页面
*/
@RequestMapping("/listCust")
public String listCustomer(Model model) {
List<Customer> custList = customerService.listCustomer();
model.addAttribute("custList",custList);
return "customerList";
}
}
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
head>
<body>
<div id="viewport">
<div id="sidebar">
<header>
<a href="#">公司后台管理a>
header>
<ul class="nav">
<li>
<a >
<i class="zmdi zmdi-view-dashboard">i> 客户管理
a>
li>
<li>
<a>
<i class="zmdi zmdi-link">i> 送水工管理
a>
li>
<li>
<a>
<i class="zmdi zmdi-widgets">i> 送水历史管理
a>
ul>
div>
<div id="content">
<nav class="navbar navbar-default">
<div class="container-fluid" >
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#"><i class="zmdi zmdi-notifications text-danger">i>
a>
li>
<li><a href="#">测试用户123a>li>
ul>
div>
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<td>客户编号td>
<td>客户名称td>
<td>客户地址td>
<td>联系方式td>
<td>水票数量td>
tr>
thead>
<tbody>
tbody>
table>
div>
div>
div>
div>
div>
div>
body>
html>
在“客户管理”菜单的超链接标签添加路径th:href="@{/cust/listCust}"
<li>
<a th:href="@{/cust/listCust}">
<i class="zmdi zmdi-view-dashboard">i> 客户管理
a>
li>
http://localhost:8091](http://localhost:8091
主页面waterMainMenu.html
和客户列表页面custList.html
存在大量重复的代码。如何解决?可以使⽤th:fragment
属性来定义被包含的模版⽚段,以供其他模版包含。
1.修改“主页面“的侧边栏
<div id="sidebar" th:fragment="sidebar">
2. 修改“主页面“的导航块
<nav class="navbar navbar-default" th:fragment="navbar">
div
标签里面的内容
<div id="sidebar" th:replace="waterMainMenu::sidebar">
div>
4.修改“客户管理“页面的导航块
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
nav>
在CustomerService
接口增加saveCustomer
方法
/**
* 添加客户信息
* @param customer 表单采集的客户信息
* @return 受影响行数,大于0添加成功,否则添加失败
*/
int saveCustomer(Customer customer);
实现CustomerService
接口的saveCustomer
方法
/**
* 添加客户信息
* @param customer 表单采集的客户信息
* @return 受影响行数,大于0添加成功,否则添加失败
*/
@Override
public int saveCustomer(Customer customer) {
return customerMapper.insert(customer);
}
当客户提交表单,将表单的客户信息持久化到数据库中,添加成功返回“用户列表”页面
/**
* 点击“添加”按钮跳转到“添加客户”页面
* @return “添加客户”页面
*/
@RequestMapping("/preSaveCust")
public String preSaveCust() {
return "custSave";
}
/**
* 添加客户信息,将表单输入的客户信息持久化到数据库中,添加成功返回客户列表页面
* @param customer
* @return
*/
@RequestMapping(value = "/saveCust",method = RequestMethod.POST)
public String saveCust(Customer customer) {
log.info("Customer = "+customer);
int rows = customerService.saveCustomer(customer);
log.info("save customer row = "+rows);
// 重定向到客户列表,将新添加的客户信息显示到客户列表
return "redirect:/cust/listCust";
}
<div class="col-md-12">
<div class="col-md-4">
<a class="btn btn-primary" th:href="@{/cust/preSaveCust}">添加客户a>
div>
div>
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
head>
<body>
<div id="viewport">
<div id="sidebar" th:replace="waterMainMenu::sidebar">
div>
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" method="post" th:action="@{/cust/saveCust}" >
<div class="form-group">
<label class="col-sm-2 control-label">客户名称label>
<div class="col-sm-5">
<input type="text" class="form-control" name="custName" placeholder="客户名称">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">客户地址label>
<div class="col-sm-5">
<input type="text" class="form-control" name="custAddress" placeholder="客户地址">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">联系方式label>
<div class="col-sm-5">
<input type="text" class="form-control" name="custMobile" placeholder="联系方式">
div>
div>
<div class="form-group" >
<label class="col-sm-2 control-label">水票数量label>
<div class="col-sm-5">
<input type="text" class="form-control" name="custTicket" placeholder="水票数量">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
div>
div>
form>
div>
div>
div>
div>
div>
div>
body>
html>
客户名称作为搜索条件,查询满足条件的客户信息。例如:使用模糊查询,搜索所有包含“老”的客户信息。
在CustomerService
接口增加searchCustomer
方法
/**
* 根据客户名称搜索满足条件客户信息
* @param custName 客户名称
* @return 客户列表
*/
List<Customer> searchCustomer(String custName);
实现CustomerService
接口的searchCustomer
方法
/**
* 根据客户名称搜索满足条件客户信息
*
* @param custName 客户名称
* @return 客户列表
*/
@Override
public List<Customer> searchCustomer(String custName) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
qw.like("cust_name",custName);
return customerMapper.selectList(qw);
}
根据表单提供的“客户名称”,查询满足条件客户信息,最后返回客户列表页面。
/**
* 根据客户名称搜索满足条件的客户信息
* @param custName 客户名称
* @param model
* @return 客户列表页面
*/
@RequestMapping("/searchCustomer")
public String searchCustomer(String custName,Model model) {
log.info("search custName = "+custName);
List<Customer> custList = customerService.searchCustomer(custName);
// 满足条件的客户列表渲染到页面
model.addAttribute("custList",custList);
return "custList";
}
<div class="col-md-8">
<form class="form-inline" th:action="@{/cust/searchCustomer}">
<input type="text" class="form-control" th:name="custName" placeholder="请输入客户名称"/>
<input type="submit" class="btn btn-primary" name="search" value="搜索"/>
form>
div>
在CustomerService
接口增加deleteCustomerById
方法
/**
* 根据客户ID删除对应的客户信息
* @param cid 客户ID
* @return 受影响行数,大于0删除成功,否则删除失败
*/
int deleteCustomerById(Integer cid);
实现CustomerService
接口的deleteCustomerById
方法
/**
* 根据客户ID删除对应的客户信息
*
* @param cid 客户ID
* @return 受影响行数,大于0删除成功,否则删除失败
*/
@Override
public int deleteCustomerById(Integer cid) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
qw.eq("cid",cid);
return customerMapper.delete(qw);
}
根据浏览器传入的客户ID删除对应的客户信息,然后返回客户列表
/**
* 根据客户ID删除客户信息,返回客户列表页面,显示删除之后的客户列表
* @param cid 客户id
* @return 客户列表
/delCust?id=1
Restful路径
/cust/delCust/{id}
*/
@RequestMapping("/delCust/{cid}")
public String deleteCustomer(@PathVariable("cid") Integer cid) {
log.info("delete Customer cid = "+ cid);
int rows = customerService.deleteCustomerById(cid);
log.info("delete customer rows = "+rows);
// 查询已删除的客户列表信息
return "redirect:/cust/listCust";
}
<td>
<a class="glyphicon glyphicon-remove" th:href="@{'/cust/delCust/'+${cust.cid}}">a>
td>
点击修改按钮,跳转到“修改客户”页面,显示要修改的客户信息。步骤如下:
1.在CustomerService
接口新增加getCustomerById
方法根据客户ID查询对应的客户信息。
/**
* 根据客户ID查询对应的客户信息
* @param cid 客户ID
* @return 客户信息
*/
Customer getCustomerById(Integer cid);
2.在CustomerServiceImpl
实现类覆写接口定义的getCustomerById
方法根据客户ID查询对应的客户信息。
/**
* 根据客户ID查询客户信息
* @param cid 客户id
* @return 客户实体
*/
@Override
public Customer getCustomerById(Integer cid) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
qw.eq("cid",cid);
return customerMapper.selectOne(qw);
}
3.在CustomerController
控制器新增preUpateCustomer
方法完成数据的回显。调用CustomerService
接口的getCustomerById
方法,将客户信息渲染到页面。
/**
* 点击“修改”按钮,页面传入的客户ID查询对应的客户信息,将查询的信息渲染到“修改客户”页面
* @param cid 客户ID
* @param model
* @return “修改客户”页面
*/
@RequestMapping("/preUpdateCust/{cid}")
public String preUpdateCustomer(@PathVariable("cid") Integer cid,Model model) {
log.info("update Customer cid = "+cid);
Customer cust = customerService.getCustomerById(cid);
model.addAttribute("cust",cust);
// 水票数量渲染到前端
return "custUpdate";
}
4 在"客户列表"页面添加“修改按钮”
<a class="glyphicon glyphicon-edit" th:href="@{'/cust/preUpdateCust/'+${cust.cid}}">a>
5.新增加“修改客户”页面。
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
head>
<body>
<div id="viewport">
<div id="sidebar" th:replace="waterMainMenu::sidebar">
div>
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" method="post" th:action="@{/cust/updateCust}" >
<input type="hidden" th:value="${cust.cid}" name="cid"/>
<div class="form-group">
<label class="col-sm-2 control-label">客户名称label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${cust.custName}"
name="custName">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">客户地址label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${cust.custAddress}"
name="custAddress">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">联系方式label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${cust.custMobile}"
name="custMobile">
div>
div>
<div class="form-group" >
<label class="col-sm-2 control-label">水票数量label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${cust.custTicket}"
name="custTicket">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
div>
div>
form>
div>
div>
div>
div>
div>
div>
body>
html>
在“修改客户”页面提交表单,将修改的数据持久化到数据库
1.在CustomerService
接口新增加updateCustomer
方法修改客户信息。
/**
* 修改客户信息
* @param customer 浏览器表单采集的客户信息
* @return 受影响行数,大于0修改成功,否则修改失败
*/
int updateCustomer(Customer customer);
2.在CustomerServiceImpl
实现类覆写接口定义的updateCustomer
方法修改客户信息。
/**
* 修改客户信息
* @param customer 浏览器表单采集的客户信息
* @return 受影响行数,大于0修改成功,否则修改失败
*/
@Override
public int updateCustomer(Customer customer) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
// update ..... where cid = ?
qw.eq("cid",customer.getCid());
return customerMapper.update(customer,qw);
}
3.在CustomerController
控制器新增upateCustomer
方法修改客户信息,然后返回客户列表显示已修改的信息
@RequestMapping(value = "/updateCust",method = RequestMethod.POST)
public String updateCustomer(Customer customer) {
log.info("update customer = "+customer);
int rows = customerService.updateCustomer(customer);
log.info("update rows = "+rows);
// 修改成功查询客户列表,跳转到客户页面
return "redirect:/cust/listCust";
}
在浏览器采集送水工信息(名称、底薪、提成、照片),然后将送水工信息持久化(插入)到对应的表中。添加送水工的核心步骤是将浏览器选择的照片上传到服务器。
配置上传文件的配置信息
# 配置浏览器上传图像到服务器的路径
location: D:/upLoad/picture/
# 配置静态资源路径
# Springboot有四个地方可以放静态资源
# classpath:/static/
# classpath:/public/
# classpath:/resources/
# classpath:/META-INF/resource/
resources:
static-locations: classpath:/static/,classpath:/public/,classpath:/resources/,classpath:/META-INF/resource/,file:${location}
# 配置上传文件大小限制
servlet:
multipart:
max-request-size: 100MB
max-file-size: 100MB
定义添加送水工对应的方法saveWorker
/**
* 添加送水工
* @param worker 送水工信息
* @return 受影响行数,大于0添加成功,否则添加失败
*/
int saveWorker(Worker worker);
在接口实现类WorkerServiceImpl
中实现接口的方法
@Override
public int saveWorker(Worker worker) {
return workerMapper.insert(worker);
}
从yml配置文件中读取服务器存放上传图像的路径
/**
* 从yml配置文件中读取服务器存放上传图像的路径
*/
@Value("${location}")
private String location;
在WorkerController控制器中定义preSaveWorker
方法,当用户点击“添加”按钮跳转到添加页面workerSave.html
@RequestMapping("/preSaveWorker")
public String preSaveWorker(){
return "workerSave";
}
在WorkerController控制器中定义saveWorker
方法。当用户提交表单将浏览器选择的文件上传到服务器中,并且将送水工信息持久化到数据库中,最后返回“送水工”列表页面,能够查看添加之后的送水工信息。
/**
添加送水工信息
步骤:
1 将浏览器选择的图像上传到服务器指定的路径
1.1 获取上传文件的名称
1.2 获取上传文件后缀的索引
1.3 获取上传文件的后缀,例如:.png
1.4 获取上传文件的前缀。前缀的格式为:1970-01-01距离现在的纳秒数。例如:1565634653563456
1.5 拼接上传文件的前缀和后缀,例如:1565634653563456.png
1.6 创建服务器存放浏览器上传文件的File对象
1.7 判断File对象的物理路径是否存在,如果不存在就创建该路径
1.8 创建上传文件的File对象
1.9 调用MultipartFile对象的transferTo方法上传文件。
1.10 将上传文件名称设置到Worker对象中
2 调用workerService对象的saveWorker方法,将送水工信息持久化到数据库
3 重定向到送水工列表,显示新增加的送水工信息
* @param worker 送水工信息
* @param file 封装了浏览器选择的送水工图像
* @return
*/
@RequestMapping(value="/workerSave",method = RequestMethod.POST)
public String saveWorker(Worker worker, MultipartFile file) {
// 条件成立:表示用户在浏览器上传了图像
if(null != file) {
// 获取上传文件的名称
String fileName = file.getOriginalFilename();
// 获取上传文件后缀的索引
int index = fileName.lastIndexOf(".");
// 获取上传文件的后缀,例如:.png
String suffix = fileName.substring(index);
// 返回1970-01-01距离现在的毫秒数作为上传文件的前缀
// 例如: 1565634653563456
long prefix = System.nanoTime();
// 拼接上传文件的前缀和后缀,例如:1565634653563456.png
String uploadFileName = prefix + suffix;
// 创建服务器存放浏览器上传文件的File对象
File uploadFile = new File(location);
// 条件成立:表示路径不存在,在服务器磁盘上创建改路径
if(!uploadFile.exists()) {
uploadFile.mkdirs();
}
// 创建上传文件的File对象
File path = new File(uploadFile,uploadFileName);
try {
file.transferTo(path);
} catch (IOException e) {
log.error("上传失败",e);
e.printStackTrace();
}
worker.setWorkerImage(uploadFileName);
}
int rows = workerService.saveWorker(worker);
log.info("worker save rows = "+rows);
return "redirect:/worker/workerList";
}
在workerList.html页面增加添加按钮
<div class="col-md-12">
<div class="col-md-4">
<a class="btn btn-primary" th:href="@{/worker/preSaveWorker}">添加a>
div>
div>
<td>
<img class="myWorkerImage"
th:if="${#strings.isEmpty(worker.workerImage)}"
src="../../images/user.png" />
<img class="myWorkerImage"
th:if="${not #strings.isEmpty(worker.workerImage)}"
th:src="'http://localhost:8091/'+${worker.workerImage}"/>
td>
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
head>
<body>
<div id="viewport">
<div id="sidebar" th:replace="waterMainMenu::sidebar">
div>
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" enctype="multipart/form-data"
method="post" th:action="@{/worker/workerSave}" >
<div class="form-group">
<label class="col-sm-2 control-label">送水工名称label>
<div class="col-sm-5">
<input type="text" class="form-control"
name="workerName" placeholder="送水工名称">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">送水工底薪label>
<div class="col-sm-5">
<input type="text" class="form-control"
name="workerSalary" placeholder="送水工底薪">
div>
div>
<div class="form-group" >
<label class="col-sm-2 control-label">送水工提成label>
<div class="col-sm-5">
<input type="text" class="form-control"
name="workerMoney" placeholder="送水工提成">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">送水工照片label>
<div class="col-sm-5">
<input type="file" class="form-control" name="file">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
div>
div>
form>
div>
div>
div>
div>
div>
div>
body>
html>
点击“修改”按钮,跳转到“修改送水工”页面,显示送水工信息
定义getWorkerById
方法,根据送水工ID获取对应的送水工信息
/**
* 根据送水工ID获取对应的送水工信息
* @param wid 送水工id
* @return 送水工信息
*/
Worker getWorkerById(Integer wid);
接口实现类WorkerServiceImpl实现WorkerService接口的getWorkerById
方法。
/**
* 根据送水工ID获取对应的送水工信息
*
* @param wid 送水工id
* @return 送水工信息
*/
@Override
public Worker getWorkerById(Integer wid) {
QueryWrapper<Worker> qw = new QueryWrapper<>();
qw.eq("wid",wid);
return workerMapper.selectOne(qw);
}
定义preUpdateWorker
方法,点击“修改”按钮,数据回显。根据id查询对应的送水工信息,并将信息渲染到“修改送水工”页面
/**
* 点击“修改”按钮,数据回显。根据id查询对应的送水工信息,并将信息渲染到“修改送水工”页面
* @param wid 送水工id
* @param model
* @return “修改送水工”页面
*/
@RequestMapping("/preUpdateWorker/{wid}")
public String preUpdateWorker(@PathVariable("wid") Integer wid,Model model) {
log.info("pre update worker wid = "+wid);
Worker worker = workerService.getWorkerById(wid);
model.addAttribute("worker",worker);
return "workerUpdate";
}
在页面中新增加修改按钮,点击“修改”按钮,跳转到workerUpdate
页面,回显送水工信息
<td>操作td>
<td>
<a class="glyphicon glyphicon-edit"
th:href="@{'/worker/preUpdateWorker/'+${worker.wid}}">a>
td>
该页面显示要修改的送水工信息(送水工名称、底薪、提成、照片)
DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> XXX送水公司后台管理系统title>
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<link rel="stylesheet" th:href="@{/css/style.css}">
<style>
img{
width:100px;
height:100px;
border:1px solid red;
}
style>
head>
<body>
<div id="viewport">
<div id="sidebar" th:replace="waterMainMenu::sidebar">
div>
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" enctype="multipart/form-data" method="post" th:action="@{/worker/updateWorker}" >
<input type="hidden" th:value="${worker.wid}" name="wid"/>
<input type="hidden" th:value="${worker.workerImage}" name="workerImage"/>
<div class="form-group">
<label class="col-sm-2 control-label">送水工名称label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${worker.workerName}"
name="workerName">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">送水工底薪label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${worker.workerSalary}"
name="workerSalary">
div>
div>
<div class="form-group">
<label class="col-sm-2 control-label">送水工提成label>
<div class="col-sm-5">
<input type="text"
class="form-control"
th:value="${worker.workerMoney}"
name="workerMoney">
div>
div>
<div class="form-group" >
<label class="col-sm-2 control-label">送水工照片label>
<div class="col-sm-3">
<input type="file" class="form-control" name="file">
div>
<div class="col-sm-2">
<img
th:if="${not #strings.isEmpty(worker.workerImage)}"
th:src="'http://localhost:8091/'+${worker.workerImage}"/>
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
div>
div>
form>
div>
div>
div>
div>
div>
div>
body>
html>
定义updateWorker
方法修改送水工信息
/**
* 修改送水工
* @param worker 送水工信息
* @return 受影响行数,大于0修改成功,否则修改失败
*/
int updateWorker(Worker worker);
接口实现类WorkerServiceImpl
实现updateWorker
方法
/**
* 修改送水工
* @param worker 送水工信息
* @return 受影响行数,大于0修改成功,否则修改失败
*/
@Override
public int updateWorker(Worker worker) {
QueryWrapper<Worker> qw = new QueryWrapper<>();
qw.eq("wid",worker.getWid());
return workerMapper.update(worker,qw);
}
/**
* 在“修改送水工”页面点击“提交”按钮,修改送水工信息,将修改的信息持久化到数据库
* @param worker 送水工信息
* @param file 封装了要上传文件的信息
* @return 送水工列表请求路径,重新查询已修改的送水工信息
*/
@RequestMapping(value="/updateWorker",method = RequestMethod.POST)
public String updateWorker(Worker worker, MultipartFile file) {
// 条件成立:表示用户在浏览器上传了图像
if(null != file) {
// 获取上传文件的名称
String fileName = file.getOriginalFilename();
// 获取上传文件后缀的索引
int index = fileName.lastIndexOf(".");
// 获取上传文件的后缀,例如:.png
String suffix = fileName.substring(index);
// 返回1970-01-01距离现在的纳秒数作为上传文件的前缀
// 例如: 1565634653563456
long prefix = System.nanoTime();
// 拼接上传文件的前缀和后缀,例如:1565634653563456.png
String uploadFileName = prefix + suffix;
// 创建服务器存放浏览器上传文件的File对象
File uploadFile = new File(location);
// 条件成立:表示路径不存在,在服务器磁盘上创建改路径
if(!uploadFile.exists()) {
uploadFile.mkdirs();
}
// 创建上传文件的File对象
// 参数1:上传文件的路径,参数2:上传文件的名称
File path = new File(uploadFile,uploadFileName);
try {
file.transferTo(path);
} catch (IOException e) {
log.error("上传失败",e);
e.printStackTrace();
}
worker.setWorkerImage(uploadFileName);
}
int rows = workerService.updateWorker(worker);
log.info("worker update rows = "+rows);
return "redirect:/worker/workerList";
}
什么是软件重构?重新组织代码结构,让你的程序更加整洁、高效的运行
为什么需要重构?添加送水工和修改送水工“上传文件”功能有大量重复的代码
@RequestMapping("/preSaveWorker")
public String preSaveWorker(){
return "workerSave";
}
/**
添加送水工信息
步骤:
1 将浏览器选择的图像上传到服务器指定的路径
1.1 获取上传文件的名称
1.2 获取上传文件后缀的索引
1.3 获取上传文件的后缀,例如:.png
1.4 获取上传文件的前缀。前缀的格式为:1970-01-01距离现在的纳秒数。例如:1565634653563456
1.5 拼接上传文件的前缀和后缀,例如:1565634653563456.png
1.6 创建服务器存放浏览器上传文件的File对象
1.7 判断File对象的物理路径是否存在,如果不存在就创建该路径
1.8 创建上传文件的File对象
1.9 调用MultipartFile对象的transferTo方法上传文件。
1.10 将上传文件名称设置到Worker对象中
2 调用workerService对象的saveWorker方法,将送水工信息持久化到数据库
3 重定向到送水工列表,显示新增加的送水工信息
* @param worker 送水工信息
* @param file 封装了浏览器选择的送水工图像
* @return
*/
@RequestMapping(value="/workerSave",method = RequestMethod.POST)
public String saveWorker(Worker worker, MultipartFile file) {
transferFile(worker, file);
int rows = workerService.saveWorker(worker);
log.info("worker save rows = "+rows);
return "redirect:/worker/workerList";
}
/**
* 处理浏览器上传文件的逻辑
* @param worker
* @param file
*/
private void transferFile(Worker worker, MultipartFile file) {
// 条件成立:表示用户在浏览器上传了图像
if (null != file) {
// 获取上传文件的名称
String fileName = file.getOriginalFilename();
// 获取上传文件后缀的索引
int index = fileName.lastIndexOf(".");
// 获取上传文件的后缀,例如:.png
String suffix = fileName.substring(index);
// 返回1970-01-01距离现在的纳秒数作为上传文件的前缀
// 例如: 1565634653563456
long prefix = System.nanoTime();
// 拼接上传文件的前缀和后缀,例如:1565634653563456.png
String uploadFileName = prefix + suffix;
// 创建服务器存放浏览器上传文件的File对象
File uploadFile = new File(location);
// 条件成立:表示路径不存在,在服务器磁盘上创建改路径
if (!uploadFile.exists()) {
uploadFile.mkdirs();
}
// 创建上传文件的File对象
// 参数1:上传文件的路径,参数2:上传文件的名称
File path = new File(uploadFile, uploadFileName);
try {
file.transferTo(path);
} catch (IOException e) {
log.error("上传失败", e);
e.printStackTrace();
}
worker.setWorkerImage(uploadFileName);
}
}
/**
* 点击“修改”按钮,数据回显。根据id查询对应的送水工信息,并将信息渲染到“修改送水工”页面
* @param wid 送水工id
* @param model
* @return “修改送水工”页面
*/
@RequestMapping("/preUpdateWorker/{wid}")
public String preUpdateWorker(@PathVariable("wid") Integer wid,Model model) {
log.info("pre update worker wid = "+wid);
Worker worker = workerService.getWorkerById(wid);
model.addAttribute("worker",worker);
return "workerUpdate";
}
/**
* 在“修改送水工”页面点击“提交”按钮,修改送水工信息,将修改的信息持久化到数据库
* @param worker 送水工信息
* @param file 封装了要上传文件的信息
* @return 送水工列表请求路径,重新查询已修改的送水工信息
*/
@RequestMapping(value="/updateWorker",method = RequestMethod.POST)
public String updateWorker(Worker worker, MultipartFile file) {
// 条件成立:表示用户在浏览器上传了图像
transferFile(worker, file);
int rows = workerService.updateWorker(worker);
log.info("worker update rows = "+rows);
return "redirect:/worker/workerList";
}
ginalFilename();
// 获取上传文件后缀的索引
int index = fileName.lastIndexOf(".");
// 获取上传文件的后缀,例如:.png
String suffix = fileName.substring(index);
// 返回1970-01-01距离现在的纳秒数作为上传文件的前缀
// 例如: 1565634653563456
long prefix = System.nanoTime();
// 拼接上传文件的前缀和后缀,例如:1565634653563456.png
String uploadFileName = prefix + suffix;
// 创建服务器存放浏览器上传文件的File对象
File uploadFile = new File(location);
// 条件成立:表示路径不存在,在服务器磁盘上创建改路径
if (!uploadFile.exists()) {
uploadFile.mkdirs();
}
// 创建上传文件的File对象
// 参数1:上传文件的路径,参数2:上传文件的名称
File path = new File(uploadFile, uploadFileName);
try {
file.transferTo(path);
} catch (IOException e) {
log.error("上传失败", e);
e.printStackTrace();
}
worker.setWorkerImage(uploadFileName);
}
}
/**
* 点击“修改”按钮,数据回显。根据id查询对应的送水工信息,并将信息渲染到“修改送水工”页面
* @param wid 送水工id
* @param model
* @return “修改送水工”页面
*/
@RequestMapping("/preUpdateWorker/{wid}")
public String preUpdateWorker(@PathVariable("wid") Integer wid,Model model) {
log.info("pre update worker wid = "+wid);
Worker worker = workerService.getWorkerById(wid);
model.addAttribute("worker",worker);
return "workerUpdate";
}
/**
* 在“修改送水工”页面点击“提交”按钮,修改送水工信息,将修改的信息持久化到数据库
* @param worker 送水工信息
* @param file 封装了要上传文件的信息
* @return 送水工列表请求路径,重新查询已修改的送水工信息
*/
@RequestMapping(value="/updateWorker",method = RequestMethod.POST)
public String updateWorker(Worker worker, MultipartFile file) {
// 条件成立:表示用户在浏览器上传了图像
transferFile(worker, file);
int rows = workerService.updateWorker(worker);
log.info("worker update rows = "+rows);
return "redirect:/worker/workerList";
}