SpringBoot开发手册

SpringBoot

这篇文章,介绍了通过SpringBoot开发的具体流程,和SpringBoot中一些常见的知识点

1、第一个HelloWorld程序

SpringBoot项目创建

Spring官网创建

https://start.spring.io/

不推荐

IDEA的Spring Initializr

File->New->Project->Spring Initializr

中途可以选择需要的组件

SpringBoot目录介绍

初始化后项目的目录

image-20210310212321422

一般情况下项目的目录结构

com
  +- example
    +- myproject
      +- Application.java
      |
      +- domain
      |  +- Customer.java
      |  +- CustomerRepository.java
      |
      +- service
      |  +- CustomerService.java
      |
      +- controller
      |  +- CustomerController.java
      |  
      +- config
      |  +- swagerConfig.java
      |
  1. Application.java是项目的启动类
  2. domain目录主要用于实体(Entity)与数据访问层(Repository)
  3. service 层主要是业务类代码
  4. controller 负责页面访问控制
  5. config 目录主要放一些配置类

新建一个Controller

新建controller包,并创建一个HelloController

增加@RestController注解

  • 这个@RestController注解,就是@Controller+@ResponseBody
// @Controller
// @ResponseBody
// 使用@RestController注解,可以替代COntroller 和ResponseBody注解
@RestController
public class HelloController {
    
    

    @RequestMapping("/hello")
    public String hello() {
    
    
        return "hello springboot";
    }
}

修改配置文件application.propertise,将端口改为2333

server.port=2333

运行测试

image-20210310213124296

小结

  • 了解了SpringBoot项目的创建

  • 了解了注解@RestController,既可以让类被Spring扫描到,又可以让返回请求不跳转到页面,而是在浏览器上显示返回内容

2、RestFul风格

RESTful Web 服务与传统的 MVC 开发一个关键区别是返回给客户端的内容的创建方式:传统的 MVC 模式开发会直接返回给客户端一个视图,但是 RESTful Web 服务一般会将返回的数据以 JSON 的形式返回,这也就是现在所推崇的前后端分离开发。

程序实例

book实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    
    
    private int id;
    private String name;
}

BookController:

@RestController
@RequestMapping("/RestFul")
public class BookController {
    
    
    private List<Book> books = new ArrayList<Book>();

    /**
     *
     * @param book 前端传入的是json类型数据
     *             而使用RequestBody,就能将Json类型数据反序列化为合适的Java对象
     * @return
     */
    @PostMapping("/add")
    public ResponseEntity<List<Book>> addBook(@RequestBody Book book) {
    
    
        books.add(book);
        return ResponseEntity.ok(books);
    }

    @DeleteMapping("/del/{id}")
    public ResponseEntity deleteBookById(@PathVariable("id") int id) {
    
    
        books.remove(0);
        return ResponseEntity.ok(books);
    }
  
    @GetMapping("/get")
    public ResponseEntity getBookByName(@RequestParam("name")String name) {
    
    
        List<Book> list = books.stream()
                .filter(book -> book.getName().equals(name))
                .collect(Collectors.toList());
        return ResponseEntity.ok(list);
    }
  //上面的也可以改成RestFul形式
	  @GetMapping("/get/{name}")
    public ResponseEntity getBookByName(@PathVariable("name")String name) {
    
    
        List<Book> list = books.stream()
                .filter(book -> book.getName().equals(name))
                .collect(Collectors.toList());
        return ResponseEntity.ok(list);
    }

    @GetMapping("/list")
    public ResponseEntity getBookList() {
    
    
        return ResponseEntity.ok(books);
    }
}
  1. @RestController **将返回的对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中。**绝大部分情况下都是直接以 JSON 形式返回给客户端,很少的情况下才会以 XML 形式返回。转换成 XML 形式还需要额为的工作,上面代码中演示的直接就是将对象数据直接以 JSON 形式写入 HTTP 响应(Response)中。关于@Controller@RestController 的对比,我会在下一篇文章中单独介绍到(@Controller +@ResponseBody= @RestController)。
  2. @RequestMapping :上面的示例中没有指定 GET 与 PUT、POST 等,因为**@RequestMapping默认映射所有HTTP Action**,你可以使用@RequestMapping(method=ActionType)来缩小这个映射。
  3. @PostMapping实际上就等价于 @RequestMapping(method = RequestMethod.POST),同样的 @DeleteMapping ,@GetMapping也都一样,常用的 HTTP Action 都有一个这种形式的注解所对应。
  4. @PathVariable :取url地址中的参数。@RequestParam url的查询参数值。
  5. @RequestBody:可以将 *HttpRequest* body 中的 JSON 类型数据反序列化为合适的 Java 类型。

image-20210311090743536

  1. ResponseEntity: 表示整个HTTP Response:状态码,标头和正文内容。我们可以使用它来自定义HTTP Response 的内容(作用)。

测试:

使用postman进行测试:

image-20210311091032158

image-20210311091143678

小结

学习了:

@GetMapping,@DeleteMapping,@PostMapping等注解

@PathVariable用来获取URL中的参数地址

@RequestParamurl查询中的参数(但这种方式,URL的请求就不是restful风格的了)

@RequestBody可以将 *HttpRequest* body 中的 JSON 类型数据反序列化为合适的 Java 类型

ResponseEntity: 表示整个HTTP Response:状态码,标头和正文内容。我们可以使用它来自定义HTTP Response 的内容。

3、SpringBoot读取配置文件

使用@Value

my-phone: 18120194475
@Value("my-phone")
    private String phoneNum;

这种方式,Spring不推荐

Spring建议使用一下方式

使用@ConfigurationProperties

配置文件:

server:
  port: 8081

my-phone: 18120194475

library:
  name: FARO_Z图书馆
  books:
    - id: 1
      name: 悲惨世界
    - id: 2
      name: 合金弹头

编写一个实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix ="library")
@Component
@PropertySource("application.yml")
public class Library {
    
    
    private String name;
    private List<Book> books;
}

@Component表示将该类识别为一个Bean

@ConfigurationProperties用于绑定属性,其中prefix表示所绑定的属性的前缀

@PropertySource(value = "application.yml")表示配置文件路径。

编写一个controller进行测试:

@RestController
public class LibraryController {
    
    
    @Autowired
    private Library lib;

    @GetMapping("/lib")
    public String getLib() {
    
    
        return lib.toString();
    }
}

@Autowired如果要用配置好的实体类的话,一定要写,这样才可以绑定

测试结果:

image-20210311095327096

小结

@ConfigurationProperties(prefix=""):用于绑定属性,其中prefix表示所绑定的属性的前缀

@PropertySource(value""):表示噢诶之文件的路径

@Autowired:对于想要使用配置的属性,一定要使用@Autowired绑定

再给出配置文件的优先级:

image-20210311102643635

4、异常处理

4.1 、SpringBoot异常处理几种方式

https://snailclimb.gitee.io/springboot-guide/#/./docs/advanced/springboot-handle-exception

4.2、SpringBoot异常处理在实际项目中的应用

https://snailclimb.gitee.io/springboot-guide/#/./docs/advanced/springboot-handle-exception-plus

5、JPA

这里我先暂时跳过,先以只用Mybatis为主

6、过滤器和拦截器

6.1、实现过滤器

在servlet中,已经对过滤器有了了解

Filter 过滤器主要是用来过滤用户请求的,它允许我们对用户请求进行前置处理和后置处理,比如实现 URL 级别的权限控制、过滤非法请求等等。

Filter 过滤器是面向切面编程——AOP 的具体实现

自定义filter的话,只要实现javax.Servlet.Filter接口,然后重写里面的三个方法即可:

public interface Filter {
    
    
   //初始化过滤器后执行的操作
    default void init(FilterConfig filterConfig) throws ServletException {
    
    
    }
   // 对请求进行过滤
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
   // 销毁过滤器后执行的操作,主要用户对某些资源的回收
    default void destroy() {
    
    
    }
}

过滤器是如何实现拦截的

Filter接口中有一个叫做 doFilter 的方法,这个方法实现了对用户请求的过滤。具体流程大体是这样的:

  1. 用户发送请求到 web 服务器,请求会先到过滤器;
  2. 过滤器会对请求进行一些处理比如过滤请求的参数、修改返回给客户端的 response 的内容、判断是否让用户访问该接口等等。
  3. 用户请求响应完毕。
  4. 进行一些自己想要的其他操作。

image-20210311101736000

编写过滤器

这里我们自定义一个过滤器:

@Component
public class MyFilter implements Filter {
    
    
    //这个是SLF4J  是类似log4j的日志实现
    private final Logger logger = LoggerFactory.getLogger(MyFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        logger.info("初始化过滤器:"+filterConfig.getFilterName());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        logger.info("过滤器开始对请求进行处理");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        System.out.println("请求接口为:"+req.getRequestURI());

        long start = System.currentTimeMillis();
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
        long end = System.currentTimeMillis();
        System.out.println("用户请求结束,请求处理耗时:"+Long.valueOf((end-start))+"ms");
    }

    @Override
    public void destroy() {
    
    
        logger.info("销毁过滤器");
    }
}
1、手动注册配置实现

配置文件中注册自定义的过滤器:

@Configuration
public class MyFilterConfig {
    
    
    @Autowired
    MyFilter myFilter;

    public FilterRegistrationBean<MyFilter> thirdFilter() {
    
    
        FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();

        filterRegistrationBean.setFilter(myFilter);

        filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/api/*")));

        return filterRegistrationBean;
    }

}
2、注解实现

在自定义的Filter上,加上@WebFilter注解

别忘记加上@Component注解,不然Spring无法扫描到,就无法实例化,就没有用:

@WebFilter(filterName = "MyFilter",urlPatterns = "/*")
@Component
public class MyFilter implements Filter {
    
    
  ...
}

其实,也可以不添加@Component注解,而是在启动类上,添加@ServletComponentScan注解,这样,Spring就会自动去找和Servlet相关的类,然后对它们进行实例化

不添加@Component注解:

@WebFilter(filterName = "MyFilter",urlPatterns = "/*")
public class MyFilter implements Filter {
    
    //不添加@Component注解
  ...
}

而是为启动类添加@ServletComponentScan注解:

@SpringBootApplication
@ServletComponentScan
public class StudyApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(StudyApplication.class, args);
    }
}

一般,还是建议加@Component

定义多个拦截器,决定执行顺序

1、配置类方式

在配置文件中调用setOrder,来设置启动优先级

2、注解方式

只要在过滤器上加上一个@Order(优先级)注解,就可以决定filter启用顺序

Filter1启动优先级设置为1:

@WebFilter(filterName = "MyFilter2",urlPatterns = "/*")
@Order(1)
@Component
public class MyFilter2 implements Filter {
    
    
}

FIlter2启动优先级设置为2:

@WebFilter(filterName = "MyFilter",urlPatterns = "/*")
@Order(2)
@Component
public class MyFilter implements Filter {
    
    
}

测试:

image-20210311132615533

6.2、实现拦截器

拦截器(Interceptor)同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。

过滤器和拦截器的区别

  • 过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(筛子)
  • 拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(关卡)

自定义拦截器

要自定义Interceptor的话,必须:

实现org.springframework.web.servlet.HandlerInterceptor接口

或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,

且要重写下面三个方法:

public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler)
 
 
public void postHandle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler,
                       ModelAndView modelAndView)
 
 
public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex)

注意: ***preHandle***方法返回 truefalse。如果返回 true,则意味着请求将继续到达 Controller 被处理。

image-20210311134606159

LoginInterceptor用于过滤所有请求:

public class LoginInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        long startTime = System.currentTimeMillis();
        System.out.println("\n-------- LogInterception.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Start Time: " + System.currentTimeMillis());

        request.setAttribute("startTime", startTime);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    

        System.out.println("\n-------- LogInterception.postHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());

        // You can add attributes in the modelAndView
        // and use that in the view page
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    

        System.out.println("\n-------- LogInterception.afterCompletion --- ");

        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("End Time: " + endTime);

        System.out.println("Time Taken: " + (endTime - startTime));
    }
}

OldLoginInterceptor,旧连接拦截器,一旦访问这个旧的连接,就会转发到 /admin/login:

public class OldLoginInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("\n-------- OldLoginInterceptor.preHandle --- ");
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Sorry! This URL is no longer used, Redirect to /admin/login");

        //getContextPath()获取的是 http://localHost。。。  即uri前面的东西
        //这里,当访问旧的废弃链接的时候,直接跳转到 /admin/login 的位置上去
        response.sendRedirect(request.getContextPath()+"/admin/login");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    

    }
}

拦截后,应该是下面这个过程:

image-20210311155721273

AdminInterceptor

public class AdminInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("\n-------- AdminInterceptor.preHandle --- ");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    

    }
}

配置类配置拦截器:

拦截器的配置类需要实现WebMvcConfigurer接口

然后,重写里面的addInterceptors方法,来配置拦截器

配置类里,可以配置每个拦截器需要拦截的路径和忽略的路径:

注意:配置类别忘记加@Configuration注解

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        //这里不添加 addPathPatterns(),就是所有路径都进行过滤
        registry.addInterceptor(new LoginInterceptor());

     
        registry.addInterceptor(new OldLoginInterceptor())
                .addPathPatterns("/admin/oldLogin");

        //excludePathPatterns是设置的忽略的路径
        registry.addInterceptor(new AdminInterceptor())
                .addPathPatterns("/admin/*")
                .excludePathPatterns("/admin/oldLogin");
    }
}

定义Controller:

@Controller
public class LoginController {
    
    

    @RequestMapping(value = {
    
    "/","/test"})
    public String test(Model model) {
    
    
        System.out.println("\n-------- MainController.test --- ");
        System.out.println(" ** You are in Controller ** ");
        return "test";
    }

    @Deprecated
    @RequestMapping("/admin/oldLogin")
    public String oldLogin(Model model) {
    
    
      
        //下面永远不会运行到
        //因为早就被拦截器拦截了
        return "oldLogin";
    }

    @RequestMapping("/admin/login")
    public String login(Model model) {
    
    
        System.out.println("\n-------- MainController.login --- ");
        System.out.println(" ** You are in Controller ** ");
        return "login";
    }
}

thymeleaf模板引擎:

如果之间创建项目的时候,没有添加thymeleaf依赖

那一定要进行下面的步骤:

  1. 导入thymeleaf依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  1. 开发环境,关闭thymeleaf缓存
#开发环境设置thymeleaf缓存不可用,加快响应速度
spring:
  thymeleaf:
    cache: false

test.html:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
 
   <head>
      <meta charset="UTF-8" />
      <title>Spring Boot Mvc Interceptor example</title>
   </head>
 
   <body>
      <div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;">
         <a th:href="@{/}">Home</a>
         &nbsp;&nbsp; | &nbsp;&nbsp;
         <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>  
      </div>
 
      <h3>Spring Boot Mvc Interceptor</h3>
       
      <span style="color:blue;">Testing LogInterceptor</span>
      <br/><br/>
 
      See Log in Console..
 
   </body>
</html>

login.html:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
   <head>
      <meta charset="UTF-8" />
      <title>Spring Boot Mvc Interceptor example</title>
   </head>
   <body>
    
      <div style="border: 1px solid #ccc;padding: 5px;margin-bottom:10px;">
         <a th:href="@{/}">Home</a>
         &nbsp;&nbsp; | &nbsp;&nbsp;
         <a th:href="@{/admin/oldLogin}">/admin/oldLogin (OLD URL)</a>  
      </div>
       
      <h3>This is Login Page</h3>
       
      <span style="color:blue">Testing OldLoginInterceptor &amp; AdminInterceptor</span>
      <br/><br/>
      See more info in the Console.
       
   </body>  
</html>

测试:

输入oldLogin:

image-20210311160551740

回车,就会跳转到login,说明oldLogin被拦截了:

image-20210311160621512

小结

  • 了解了过滤器,拦截器的区别:

一个是筛子,一个是关卡

  • 学习了SpringBoot中过滤器的配置:
  1. 创建自定义过滤器类,实现Filter接口,复习而其中三个方法
  2. 使用注解或者手动配置配置文件
    • 注解:@WebFilter(filterName = “MyFilterWithAnnotation”, urlPatterns = “/api/*”)
    • 配置文件的方式,翻阅上面的文档
  • 学习了SpringBoot中拦截器的配置:
  1. 创建自定义拦截器,并实现HanderInterceptor接口
  2. 创建拦截器配置类,实现WebMvcConfigurer接口,为每个拦截器进行配置(配置拦截路径或者忽略路径)

7、整合Mybatis

这里先给出SpringBoot项目的完整项目结构:

image-20210311164106684

下面是整合步骤:

  1. 新建数据库表 person:
DROP TABLE IF EXISTS `user`;
CREATE TABLE user (
`id` int(15) AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
`pwd` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY(id)
)
  1. 导入Mybatis和mysql的依赖:

也可以在新建项目的时候,导入相关的模块

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
  1. 注意Maven静态资源到处问题
	<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
        <resources>
            <!--此处的配置是识别到mapper.xml文件,也可以在application.properties中配置-->
            <!--即静态资源导出问题-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
  1. 修改配置文件:
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springboot-mybatis?useUnicode=true&characterEncoding=utf-8
    username: admin
    password: 123
    driver-class-name: com.mysql.cj.jdbc.Driver
  1. 先测试一下,看看有没有配置成功:
@SpringBootTest
class SpringbootStudy3ApplicationTests {
    
    

    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
    
    
        System.out.println(dataSource.getClass());
        System.out.println(dataSource.getConnection());
    }
}

image-20210311194520302

  1. 编写Mapper接口:

注意:根据官方文档,mapper接口,一定要加上@Mapper注解和@Repository注解

@Repository注解的功能和@Component一样,只是@Repository是用在Dao层的

@Mapper
@Repository //和@Component功能一样,只是用在Dao层
public interface UserMapper {
    
    

    List<User> queryUserList();

    User queryUserById(@Param("id") int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);


}
  1. 编写xml实现

这里的xml实现,是放在 resources/mybatis/mapper 下的

image-20210311210125098

想要和接口绑定,还需要在配置文件中配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.faroz.mapper.UserMapper">
    <select id="queryUserList" resultType="User">
        select * from user
    </select>

    <select id="queryUserById" parameterType="_int" resultType="User">
        select * from user where id=#{id}
    </select>

    <insert id="addUser" parameterType="User">
        insert into user values(#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser">
        update user
        set name=#{name},pwd=#{pwd}
        where id=#{id}
    </update>

    <delete id="deleteUser" parameterType="_int">
        delete from user where id=#{id}
    </delete>

</mapper>
  1. 配置Mybatis

上面的yml配置其实没有配置完,只配置了一个数据源,其实,还要再配置一下Mybatis,

比如上面的xml和接口的配置问题

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springboot-mybatis?useUnicode=true&characterEncoding=utf-8
    username: admin
    password: 123
    driver-class-name: com.mysql.cj.jdbc.Driver

# 整合Mybatis
mybatis:
  type-aliases-package: top.faroz.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

  1. 编写Controller进行测试
@RestController
@RequestMapping("/user")
public class UserController {
    
    

    @Autowired
    private UserMapper mapper;

    @GetMapping("/list")
    public ResponseEntity queryUserList() {
    
    
        List<User> list = mapper.queryUserList();
        return ResponseEntity.ok(list);
    }

    @GetMapping("/list/{id}")
    public ResponseEntity queryUserById(@PathVariable("id")int id) {
    
    
        User user = mapper.queryUserById(id);
        return ResponseEntity.ok(user);
    }

    @PostMapping("/add")
    public String addUser(@RequestBody User user) {
    
    
        mapper.addUser(user);
        return "添加成功!";
    }

    @PostMapping("/update")
    public String updateUser(@RequestBody User user) {
    
    
        mapper.updateUser(user);
        return "修改成功!";
    }

    @GetMapping("/delete/{id}")
    public String deleteUser(@PathVariable("id") int id) {
    
    
        mapper.deleteUser(id);
        return "删除成功!";
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44062380/article/details/114701094