【SpringMVC】| RESTful架构风格、RESTful案例(CRUD)

目录  

 

RESTful架构风格

1. RESTful简介

2. RESTful的实现

3. HiddenHttpMethodFilter

RESTful案例(CRUD)

1. 准备工作

2. 功能清单

列表功能(显示数据) 

删除数据(难点)

添加数据 

更新数据

图书推荐:用ChatGPT与VBA一键搞定Excel


RESTful架构风格

1. RESTful简介

REST:Representational State Transfer,表现层资源状态转移

a>资源

        资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。

b>资源的表述

        资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如:HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

c>状态转移

        状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

2. RESTful的实现

(1)具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源POST 用来新建资源PUT 用来更新资源DELETE 用来删除资源

(2)REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开(前端是一杠一值、后端是一杠一大括号),不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。

操作传统方式REST风格
查询操作getUserById?id=1user/1-->get请求方式
保存操作saveUseruser-->post请求方式
删除操作deleteUser?id=1user/1-->delete请求方式
更新操作updateUseruser-->put请求方式

3. HiddenHttpMethodFilter

(1)由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求!

(2)HiddenHttpMethodFilter 处理put和delete请求的条件

①当前请求的请求方式必须为:post

②当前请求必须传输请求参数:_method(这个参数有三个值:put、delete、patch

(3)满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_method的值才是最终的请求方式。

 在web.xml中注册HiddenHttpMethodFilter

    <filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

注:目前为止,SpringMVC中提供了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter在web.xml中注册时必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter。

原因:在 CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的;request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作; 而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:

String paramValue = request.getParameter(this.methodParam);

发送Get、Post、Put、Delete请求实操

前端发送请求:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--发送Get请求-->
<a th:href="@{/user}">查询所有用户信息</a><br>
<a th:href="@{/user/1}">根据id查询用户信息</a><br>
<!--发送Post请求-->
<form th:action="@{/user}" method="post">用户:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" name="Post提交"><br>
</form><!--发送put请求-->
<form th:action="@{/user}" method="post"><!--设置隐藏域的请求类型--><input type="hidden" name="_method" value="put"><br>用户:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" name="Put提交"><br>
</form>
<!--发送delete请求-->
<form th:action="@{/user/2}" method="post"><input type="hidden" name="_method" value="delete"><br><input type="submit" name="Delete提交"><br>
</form>
</body>
</html>

后端接收请求:

注:执行删除操作时一般都是使用超链接,但是一般都是和Vue或者ajax相关联;这里就是用form表单的形式,但是使用form表单执行删除操作时,不能使用@RequestMappping注解,然后method属性去指定请求的方式(会报错)。直接使用派生注解@DeleteMapping就没事

package com.zl.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;/*** 使用Restful模拟用户资源的增删改查* /user    Get     查询所有用户信息* /user/1  Get     根据用户id查询用户信息* /user    Post    添加用户信息* /user/1  Delete  根据用户id删除用户信息* /user    Put     修改用户信息*/
@Controller
public class UserController {@RequestMapping("/")public String forwardIndex(){return "index";}// 发送Get查询所有@RequestMapping(value = "/user",method = RequestMethod.GET)public String getAllUser(){System.out.println("查询所有用户信息");return "success";}// 发送Get查询一个@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)public String getUserById(@PathVariable String id){System.out.println("根据用户id查询用户信息"+id);return "success";}// 发送Post增加@RequestMapping(value = "/user",method = RequestMethod.POST)public String insertUser(String username,String password){System.out.println("成功添加用户:"+username+"密码是:"+password);return "success";}// 发送put修改@RequestMapping(value = "/user",method = RequestMethod.PUT)public String putUser(){System.out.println("修改用户信息");return "success";}// 发送Delete删除// @RequestMapping(value = "/user/{id}}",method = RequestMethod.DELETE)@DeleteMapping(value = "/user/{id}")public String deleteUserById(@PathVariable String id){System.out.println("根据用户id删除用户信息:"+id);return "success";}
}

RESTful案例(CRUD)

1. 准备工作

搭建环境

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>springmvc-thymeleaf-restful</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>springmvc-thymeleaf-restful Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.10.RELEASE</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency></dependencies><!--指定资源文件的位置--><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include><include>**/*.properties</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.xml</include><include>**/*.properties</include></includes></resource></resources></build></project>

web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<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"><!--注册过滤器:解决post请求乱码问题--><filter><filter-name>encode</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!--指定字符集--><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><!--强制request使用字符集encoding--><init-param><param-name>forceRequestEncoding</param-name><param-value>true</param-value></init-param><!--强制response使用字符集encoding--><init-param><param-name>forceResponseEncoding</param-name><param-value>true</param-value></init-param></filter><!--所有请求--><filter-mapping><filter-name>encode</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--发送put、delete请求方式的过滤器--><filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--注册SpringMVC框架--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--配置springMVC位置文件的位置和名称--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--将前端控制器DispatcherServlet的初始化时间提前到服务器启动时--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!--指定拦截什么样的请求例如:http://localhost:8080/demo.action--><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"xmlns:mvc="http://www.springframework.org/schema/mvc"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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--配置包扫描--><context:component-scan base-package="com.zl"/><!--视图控制器,用来访问首页;需要搭配注解驱动使用--><mvc:view-controller path="/" view-name="index"/><!--专门处理ajax请求,ajax请求不需要视图解析器InternalResourceViewResolver--><!--但是需要添加注解驱动,专门用来解析@ResponseBody注解的--><!--注入date类型时,需要使用@DateTimeFormat注解,也要搭配这个使用--><mvc:annotation-driven/><!-- 配置Thymeleaf视图解析器 --><bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean></beans>

准备实体类

package com.zl.bean;public class Employee {private Integer id;private String lastName;private String email;private Integer gender;@Overridepublic String toString() {return "Employee{" +"id=" + id +", lastName='" + lastName + '\'' +", email='" + email + '\'' +", gender=" + gender +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Integer getGender() {return gender;}public void setGender(Integer gender) {this.gender = gender;}public Employee(Integer id, String lastName, String email, Integer gender) {super();this.id = id;this.lastName = lastName;this.email = email;this.gender = gender;}public Employee() {}
}

准备dao模拟数据:使用Map集合的操作模拟连接数据库

package com.zl.dao;import com.zl.bean.Employee;
import org.springframework.stereotype.Repository;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;@Repository
public class EmployeeDao {private static Map<Integer, Employee> employees = null;static{employees = new HashMap<Integer, Employee>();employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));}private static Integer initId = 1006;public void save(Employee employee){if(employee.getId() == null){employee.setId(initId++);}employees.put(employee.getId(), employee);}public Collection<Employee> getAll(){return employees.values();}public Employee get(Integer id){return employees.get(id);}public void delete(Integer id){employees.remove(id);}
}

2. 功能清单

功能URL 地址请求方式
访问首页√/GET
查询全部数据√/employeeGET
删除√/employee/2DELETE
跳转到添加数据页面√/toAddGET
执行保存√/employeePOST
跳转到更新数据页面√/employee/2GET
执行更新√/employeePUT

列表功能(显示数据) 

index.html:发送请求,查询所有员工

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>首页</h1>
<a th:href="@{/employee}">查看员工信息</a></body>
</html>

EmployeeController:接收请求,拿到数据放到域对象当中去;并跳转页面展示数据

package com.zl.controller;import com.zl.bean.Employee;
import com.zl.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Collection;
import java.util.Iterator;@Controller
public class EmployeeController {@Autowiredprivate EmployeeDao employeeDao;// 查看员工信息@GetMapping("/employee")public String getEmployees(Model model){Collection<Employee> employees = employeeDao.getAll();System.out.println(employees);// 放到域对象当中model.addAttribute("employees",employees);// 跳转页面进行数据的展示return "employee_list";}}

employee_list.html:展示数据

①前端中两个重要的标签from和table:from是用来发送请求的,table是用来展示数据的。border属性表示设置边框、cellpadding和cellspacing表示设置边框的边距和间距为0、style是用来设置居中操作的(也可以直接用align="center")。

②使用thymeleaf便利数据,很类似以与JSTL标签库的使用,格式不同罢了;这是使用的是thymeleaf的each标签,格式为:"自定义变量名:放入域对象数据的key"

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Employee Info</title>
</head>
<body>
<!--表格展示数据:居中、边框的边距和间距设为0-->
<table border="1" style="text-align: center" cellpadding="0" cellspacing="0" ><tr><!--colspan合并单元格,表示当前字段占用5个单元格--><th colspan="5">Employee Info</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options</th></tr><!--使用thymeleaf遍历数据,类似于JSTL标签库--><tr th:each="employee : ${employees}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><a href="">delete</a><a href="">update</a></td></tr>
</table></body>
</html>

效果展示:

删除数据(难点)

问题:删除操作处理超链接地址?

通过id进行删除操作,但是此时的id需要动态获取,不能写死!

<a th:href="@{/employee/${employee.id}}">delete</a>

如果直接使用${employee.id}的方式添加在路径后面,此时大括号{}会被thymeleaf解析!

解决方案一: 使用+号拼接,拼接在@{}外面,这样就不会被thymeleaf解析

<!--放到@{}外面,此时的 加号+ 会报错,但不影响使用-->
<a th:href="@{/employee/}+${employee.id}">delete</a>

解决方案二: 也可以就拼接在@{}里面,此时的路径/employee/需要加上单引号

<!--加上单引号的表示会被当做路径解析,后面的则会被当做数据解析-->
<a th:href="@{'/employee/'+${employee.id}}">delete</a>

问题:通过超链接控制表单的提交?

通过Vue实现超链接控制form表单的提交!

注:在webapp/static/js下导入vue.js库!

①首先需要创建Vue,在Vue中绑定容器;我们需要操作超链接,所以绑定的元素必须包括我们要操作的元素。所以可以在tr或者table标签中定义一个id进行绑定。

②设置超链接的点击事件,在删除的超链接中使用@click绑定一个点击事件;然后在Vue的methods种处理绑定事件。

③获取form表单,所以要给from表单设置id,进行获取,获取到表单以后将触发事件的超连接的href属性赋值给表单的action、提交表单、取消超连接的默认行为。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Employee Info</title></head>
<body>
<!--表格展示数据:居中、边框的边距和间距设为0-->
<table id="dataTable" border="1" style="text-align: center" cellpadding="0" cellspacing="0" ><tr><!--colspan合并单元格,表示当前字段占用5个单元格--><th colspan="5">Employee Info</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options</th></tr><!--使用thymeleaf遍历数据,类似于JSTL标签库--><tr th:each="employee : ${employees}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><!--删除操作,超链接控制form表单--><a @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a><a href="">update</a></td></tr>
</table><!--表单-->
<form  id="deleteForm" method="post"><input type="hidden" name="_method" value="delete" />
</form>
<!--引入Vue-->
<script type="text/javascript" th:src="@{/static/js/vue.js}" />
<!--使用js代码-->
<script type="text/javascript">// 创建Vuevar vue = new Vue({// 绑定容器(使用el属性)el:"#dataTable",// 处理绑定事件(使用methods属性)methods:{// 函数的名称和对应的函数deleteEmployee:function(event){ // event代表当前的点击事件// 根据id获取form表单元素var deleteForm = document.getElementById("deleteForm");// 将触发事件的超连接的href属性赋值给表单的actiondeleteForm.action = event.target.href;// 提交表单deleteForm.submit();// 取消超连接的默认行为event.preventDefault();}}});
</script></body>
</html>

根据id删除

注:此时会遇到使用转发还是重定向的问题;删除过后就和当前页面没关系,是要跳转到另一个页面,并且地址栏的地址肯定也要变,所以使用重定向!

    // 根据id删除员工@DeleteMapping("/employee/{id}")public String deleteEmployee(@PathVariable Integer id){employeeDao.delete(id);// 重定向到列表页面return "redirect:/employee";}

问题1:此时重新部署进行访问,此时浏览器会报错误(发送的还是get请求,绑定的事件没起作用)

F12代开调试窗口,发现是找不到vue.js

 此时打开当前工程打的war包发现没有static的目录

 解决方案:重新进行打包

问题2: 上面是解决了当前项目没有,所以找不到;重新打包以后当前服务器已经有了,发现还是找不到!

解释:此时是因为前端控制器DispatcherServlet引起的,因为我们设置的处理路径是"/",表示除了jsp的所有路径,此时的静态资源vue.js被SpringMVC处理了,但是静态资源又不能被SpringMVC处理。此时需要一个default-servlet-handler开放对静态资源的访问!

<!--开放对静态资源的访问-->
<mvc:default-servlet-handler />

<mvc:default-servlet-handler />工作的原理:

首先静态资源会被SpringMVC的前端控制器DispatcherServlet处理,如果在前端的控制器中找不到相对应的请求映射,此时就会交给默认的Servlet处理,如果默认的Servlet能找到资源就访问资源,如果找不到就报404!

问题3:此时浏览器还可能报错

解释:您正在开发模式下运行Vue。部署生产时,请确保打开生产模式。

根据提示来做 , 将生产模式的提示关闭即可 ,即设置成 false即可

<script>Vue.config.productionTip= false </script>

此时就可以正常的进行删除操作 

添加数据 

编写超链接,跳转到添加页面

<th>options(<a th:href="@{/toAdd}">add</a>)</th>

此时不需要任何的业务逻辑,使用视图控制器

<mvc:view-controller path="/toAdd" view-name="employee_add"/>

 添加数据的employee_add

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>add employee</title>
</head>
<body><!--添加数据的表单-->
<form th:action="@{/employee}" method="post">lastName:<input type="text" name="lastName"><br>email:<input type="text" name="email"><br>gender:<input type="radio" name="gender" value="1">male<input type="radio" name="gender" value="0">female<br><input type="submit" value="add"><br>
</form></body>
</html>

获取form表单提交的数据,进行添加

    // 添加数据@PostMapping("/employee")public String addEmployee(Employee employee){employeeDao.save(employee);// 重定向到列表页面return "redirect:/employee";}

添加成功

更新数据

根据id进行修改

<!--修改操作-->
<a th:href="@{'/employee/'+${employee.id}}">update</a>

注:这里涉及一个回显数据的功能,所以需要先跳转到一个Controller去查询数据,把数据放到域对象当中后跳转到一个新的页面employee_update页面显示,通过这个页面进行显示的数据进行修改,修改后并提交在经过一个Controller处理冲转到页面展示功能页面进行数据的展示!

根据id先查询数据

   // 用户回显数据的controller@RequestMapping("/employee/{id}")public String getEmployeeById(@PathVariable Integer id,Model model){// 根据id查Employee employee = employeeDao.get(id);// 存到域对象当中model.addAttribute("employee",employee);// 跳转到回显数据的页面return "employee_update";}

回显数据并可以更新数据的employee_update

对于单显框的回显使用的是field属性!

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>update employee</title>
</head>
<body><!--回显数据的表单-->
<form th:action="@{/employee}" method="post"><!--发送put请求--><input type="hidden" name="_method" value="put"><!--id也回显,设置为隐藏域,或者设置为只读--><input type="hidden" name="id" th:value="${employee.id}">lastName:<input type="text" name="lastName" th:value="${employee.lastName}"><br>email:<input type="text" name="email" th:value="${employee.email}"><br>gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}">male<input type="radio" name="gender" value="0" th:field="${employee.gender}">female<br><input type="submit" value="update"><br>
</form></body>
</html>

效果展示:默认回显数据的效果

在上面回显数据的页面进行更新,根据更新提交的数据进行存储,然后重定向到列表页面展示

    // 更新数据的Controller@PutMapping("/employee")public String updateEmployee(Employee employee){// 更新数据employeeDao.save(employee);// 重定向到列表页面return "redirect:/employee";}

图书推荐:用ChatGPT与VBA一键搞定Excel

参与方式:

本次送书 1 本! 
活动时间:截止到 2023-06-12 00:00:00。

抽奖方式:利用程序进行抽奖。

参与方式:关注博主(只限粉丝福利哦)、点赞、收藏,评论区随机抽取,最多三条评论!

本期图书:《用ChatGPT与VBA一键搞定Excel》

        在以 ChatGPT 为代表的 AIGC(AI Generated Content,利用人工智能技术来生成内容)工具大量涌现的今天,学习编程的门槛大幅降低。对于大部分没有编程基础的职场人士来说,VBA 这样的办公自动化编程语言比以前任何时候都更容易掌握,能够极大提高工作效率。本书通过 3 个部分:VBA 基础知识、ChatGPT基础知识、ChatGPT实战办公自动化,帮助Excel用户从零开始迅速掌握VBA,以“授人以渔”的方式灵活应对任何需要自动化办公的场景。

        简而言之,本书的目标是:普通用户只需要掌握一些VBA的基本概念,然后借助 ChatGPT 就可以得到相应的VBA代码,从而解决具体问题。

京东购买链接:点击购买

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【送书福利】普通用户“快速进阶”与资深玩家“解锁大招”的实用秘籍:《用ChatGPT与VBA一键搞定Excel》

本文目录 摘要作者简介本书特色内容简介送书福利 摘要 Excel是一款广泛应用于数据处理和分析的工具&#xff0c;而VBA&#xff08;Visual Basic for Applications&#xff09;是一种用于编程自动化Excel操作的语言。然而&#xff0c;对于非专业的Excel用户来说&#xff0c;VBA编…

ChatGPT与Excel结合_编写VBA宏

先来解释下什么是Excel vba宏 ⭐Excel VBA宏&#xff08;Visual Basic for Applications&#xff09;是一种用于在Microsoft Excel中自动化和扩展功能的编程语言。VBA允许用户编写自定义的脚本或宏&#xff0c;以便通过执行一系列指令来自动完成特定任务。 使用Excel VBA宏&a…

Cursor--基于ChatGPT的辅助编程软件

Cursor--基于ChatGPT的辅助编程软件 简述下载安装软件使用感想 简述 Cursor是一款与OpenAI合作并且基于ChatGPT的新一代辅助编程软件&#xff0c;不用科学上网&#xff0c;使用简单。 下载安装 下载网址&#xff1a; https://www.cursor.so/步骤&#xff1a; 1.打开网址&am…

为什么很多公司选择在年底裁员?

裁员是每年年底都无法避免的话题&#xff0c;尤其是今年&#xff0c;显得更为突出。裁人的速度也是一次次被刷新&#xff1a;有的上午还在过需求&#xff0c;下午就通知走人&#xff1b;有的吃个午饭回来就已经没有打开电脑的权限了…其中还有不少是处于实习阶段的应届毕业生&a…

美国最大运营商裁员4.4万人,作为普通的程序员,我们该如何面对互联网裁员浪潮?

近日&#xff0c;面对难看的财务报表&#xff0c;美国最大的通讯运营商、市值2200亿美金的Verizon&#xff0c;遣散了4.4万名老员工。 在国内&#xff0c;解决了80%就业的中小企业也遭遇了新一轮生存困境…社会很残酷&#xff0c;追求稳定的人都被时代抛弃&#xff0c;有远见的…

JobShow裁员加班实况

如何写一份好的简历&#xff1f; 写在前面 在内推的时候很多同学问到如何能够让自己的简历更出彩&#xff0c;在帮助修改简历的过程中&#xff0c;发现了一些通用的问题&#xff0c;简单写个帖子总结下&#xff0c;如有错误请批评指正 格式 好的简历能够让HR一眼看到最重要的…

上了RPA,裁员40%,公司盈利了

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) E总是一家电商公司老板&#xff0c;在淘宝、京东、拼多多、抖音、快手都有店铺&#xff0c;经营3C数码类商品。每年营业额有几个亿&#xff0c;按毛利25%计算&#xff0c;也有大几千万了&#xff0c;但…

一知名公司裁员,网友爆料称裁 80%…

大家好~ 最近的瓜真的是一个接一个&#xff0c;这次彻底麻了&#xff0c;吃着薇娅逃税的瓜的同时&#xff0c;蘑菇街开始裁员了&#xff0c;而且这次技术是大规模的裁员。 第一时间上脉脉去看&#xff0c;果然已经有对应的讨论了。80%是真的夸张~ 然后得到结论基本上是&#…

想辞职了,IT部门地位低,在公司天天被业务压制,成了取数机器

最近被业务搞烦了&#xff0c;一天到晚除了让我取数就是找我解决报表问题。我自己一堆开发任务没做完&#xff0c;整天就是被业务打断&#xff0c;导致一年了自己技术丝毫没提升。最重要的是&#xff0c;做的事情完全不被认可&#xff0c;业务只当你是工具人&#xff0c;老板也…

谷歌裁员细节曝光:高绩效员工、开源主管被裁,61岁程序员在线求职,有人60天找不到工作就被遣返...

文章来源&#xff1a;量子位 | 公众号 QbitAI 大家好&#xff01;我是韩老师。 最近几个月&#xff0c;裁员似乎已经成为了科技巨擘们的代名词&#xff0c;不禁让人们对于经济发展的前景感到担忧。 其中&#xff0c;谷歌母公司 Alphabet 此前宣称&#xff0c;变化的经济现状迫使…

Google率先宣布取消部分offer,新一轮裁员潮真的来了?

目前美国累计确诊病例数已超过33万&#xff0c;每天2万的新增病例&#xff0c;还不知何时能减缓。受此影响&#xff0c;本该offer满天飞的季节&#xff0c;却面临着“裁员降薪、冻结offer”的境遇。 早前&#xff0c;Google就已经率先宣布取消部分在match阶段的实习pending of…

疫情之下德国公司纷纷裁员,程序员呢?

有一个好消息&#xff0c;和一个坏消息&#xff0c;先听哪个&#xff1f; 我们先听坏消息吧。 1坏消息 南德约有20%的公司正在裁员&#xff0c;或正在裁员的路上。 根据德国Ifo经济研究所的一项调查&#xff0c;巴符州和巴伐利亚州有约20%的公司已经决定裁员&#xff0c;疫情危…

裁员先兆?腾讯员工吐槽:公司发起PIP,PCG的鹅们,自求多福吧

前言&#xff1a;如今的我们身处一个信息爆炸的时代&#xff0c;各类八卦新闻、小道消息更是如此。在我们的印象中&#xff0c;“八卦”似乎总是跟“女人”挂钩。但笔者可以明确的告诉你&#xff0c;职场男士在吃饭、茶歇、网聊或者发短信时八卦也不差于女人。“八卦”看似是某…

辞退“脚踏两家公司”的工程师后,CEO被网暴!

几日前&#xff0c;软件公司 Canopy CEO Davis Bell 在自己的 Linkedln 上发布了一篇短文&#xff0c;声称自己公司刚刚辞退了两名身兼多份全职工作的员工。不过网友似乎并不买账&#xff0c;反对的声音非常多&#xff0c;甚至还对其进行“死亡威胁”。 全职打多份工&#xff0…

jvm崩溃的原因_JVM崩溃时:如何调查最严重错误的根本原因

jvm崩溃的原因 当应用程序崩溃时&#xff0c;您可以学到什么&#xff1f; 我认为&#xff0c;“后见之明是20 /”是最喜欢的短语之一托马斯罗梅尔 &#xff0c;工程ZeroTurnaround的副总裁。 好吧&#xff0c;我实际上不确定在他的短语中占什么位置&#xff0c;但是我已经听过…

做外贸怎么找客户

现在国内贸易内卷非常严重&#xff0c;很多商家都转向海外市场了&#xff0c;总结而言&#xff0c;目前所有做外贸的人&#xff0c;核心的点就是要找到重点意向客户&#xff0c;今天就和大家分享一下目前市面上外贸找客户的几种方法。 主动出击式开发外贸客户 1、参加展会找外贸…

chatGPT入世,外贸企业如何充分利用?

当今时代&#xff0c;随着互联网的不断发展和普及&#xff0c;越来越多的外贸企业开始意识到数字化转型的重要性。数字化转型不仅可以提高企业的生产效率和质量&#xff0c;更可以提升企业在全球市场的竞争力。在数字化转型的过程中&#xff0c;将ChatGPT和AI数字人相结合是一种…

ChatGPT 做PPT只要3分钟?

ChatGPT 这个风口&#xff0c;我们普通人应如何抓住机会逆袭。 让我们一起来了解一下吧&#xff01; 如何三分钟搞定一份 PPT&#xff0c;只需要三个步骤。和我一起来操作一遍吧&#xff01; 这里会教大家如何使用ChatGPTMindShow自动生成PPT。 一、获取PPT大纲 我们首先要…

ChatGPT让Python再次伟大!

ChatGPT的爆火改变了很多东西&#xff0c;就与多年前移动互联网的普及一样&#xff0c;我们正处于AI改变世界的前夜。 在OpenAI为其推出了GPT-4语言模型后&#xff0c;ChatGPT的回答准确性有了极大提高&#xff0c;也具备了更高水平的识图能力&#xff0c;这让ChatGPT成为了“…

“盗窃”而来的 3000 亿单词?ChatGPT 摊上事了,遭索赔 30 亿美元!

省时查报告-专业、及时、全面的行研报告库 省时查方案-专业、及时、全面的营销策划方案库 【免费下载】2023年5月份全网热门报告合集 普通人如何利用ChatGPT变现赚钱&#xff1f; 无需翻墙&#xff0c;无需注册&#xff0c;ChatGPT4直接使用 ChatGPT提词手册&#xff0c;学完工…