使用 Spring Boot 和 MyBatis 构建 REST CRUD API

Dear 丶 2023-10-01 03:30 110阅读 0赞

大家好,这里我们将学习如何使用 Spring Boot、MyBatis 和带有 Annotation 映射的 H2 数据库开发 REST 风格的 CRUD API。您可以从我们的 Github 存储库下载源代码。

更多相关主题:

  • Spring + Groovy 模板 CRUD 示例
  • Spring Boot + FreeMarker + JPA - CRUD 示例
  • Spring Boot + Mustache + JPA - CRUD 示例
  • Spring Boot - JPA- Thymeleaf- CRUD 项目

使用的技术:

  • Spring Boot 2.5.4
  • Spring 5.3.9
  • MyBatis 2.2.0
  • Java 11
  • Maven 3

完成本教程后,我们将构建什么?

我们将构建 REST API CRUD 功能:

  1. GET - 获取所有用户:/api/v1/users
  2. GET - 按 ID 获取用户:/api/v1/users/{id}
  3. POST - 创建用户:/api/v1/users
  4. PUT - 编辑用户详细信息:/api/v1/users/{id}
  5. DELETE - 删除用户:/api/v1/users/{id}

项目目录:

  1. ├─src
  2. ├─main
  3. ├─java
  4. └─com
  5. └─knf
  6. └─dev
  7. └─demo
  8. └─springbootmybatiscrudexample
  9. SpringbootMybatisCrudExampleApplication.java
  10. ├─controller
  11. UserController.java
  12. ├─exception
  13. CustomErrorResponse.java
  14. GlobalExceptionHandler.java
  15. UserIdAlreadyExistException.java
  16. UserIdNotFoundException.java
  17. ├─model
  18. User.java
  19. └─repository
  20. UserRepository.java
  21. └─resources
  22. application.properties
  23. schema.sql

Maven 依赖项(pom.xml)

放置 mybatis -spring-boot-starter , h2依赖。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. https://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>2.5.4</version>
  11. <relativePath/> <!-- lookup parent from repository -->
  12. </parent>
  13. <groupId>com.knf.dev.demo</groupId>
  14. <artifactId>springboot-mybatis-crud-example</artifactId>
  15. <version>0.0.1-SNAPSHOT</version>
  16. <name>springboot-mybatis-crud-example</name>
  17. <description>Demo project for Spring Boot</description>
  18. <properties>
  19. <java.version>11</java.version>
  20. </properties>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-web</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.mybatis.spring.boot</groupId>
  28. <artifactId>mybatis-spring-boot-starter</artifactId>
  29. <version>2.2.0</version>
  30. </dependency>
  31. <dependency>
  32. <groupId>com.h2database</groupId>
  33. <artifactId>h2</artifactId>
  34. <scope>runtime</scope>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-test</artifactId>
  39. <scope>test</scope>
  40. </dependency>
  41. </dependencies>
  42. <build>
  43. <plugins>
  44. <plugin>
  45. <groupId>org.springframework.boot</groupId>
  46. <artifactId>spring-boot-maven-plugin</artifactId>
  47. </plugin>
  48. </plugins>
  49. </build>
  50. </project>

数据库设置

我们将创建一个名为 users 的表,其中包含一些简单的列。

我们可以通过在资源中创建一个 schema.sql 文件来初始化一个模式。

  1. create table users
  2. (
  3. id integer not null,
  4. firstName varchar(255) not null,
  5. lastName varchar(255) not null,
  6. emailId varchar(255) not null,
  7. primary key(id)
  8. );

创建用户模型

  1. package com.knf.dev.demo.springbootmybatiscrudexample.model;
  2. public class User {
  3. private long id;
  4. private String firstName;
  5. private String lastName;
  6. private String emailId;
  7. public User() {
  8. }
  9. public User(long id,String firstName,
  10. String lastName, String emailId) {
  11. super();
  12. this.id=id;
  13. this.firstName = firstName;
  14. this.lastName = lastName;
  15. this.emailId = emailId;
  16. }
  17. public long getId() {
  18. return id;
  19. }
  20. public void setId(long id) {
  21. this.id = id;
  22. }
  23. public String getFirstName() {
  24. return firstName;
  25. }
  26. public void setFirstName(String firstName) {
  27. this.firstName = firstName;
  28. }
  29. public String getLastName() {
  30. return lastName;
  31. }
  32. public void setLastName(String lastName) {
  33. this.lastName = lastName;
  34. }
  35. public String getEmailId() {
  36. return emailId;
  37. }
  38. public void setEmailId(String emailId) {
  39. this.emailId = emailId;
  40. }
  41. }

创建用户 MyBatis 存储库

默认情况下,MyBatis-Spring-Boot-Starter 将搜索标有 @Mapper 注释的映射器。在此示例中,我们没有使用 XML 映射。

  1. package com.knf.dev.demo.springbootmybatiscrudexample.repository;
  2. import com.knf.dev.demo.springbootmybatiscrudexample.model.User;
  3. import org.apache.ibatis.annotations.*;
  4. import java.util.List;
  5. @Mapper
  6. public interface UserRepository {
  7. @Select("select * from users")
  8. public List<User> findAll();
  9. @Select("SELECT * FROM users WHERE id = #{id}")
  10. public User findById(long id);
  11. @Delete("DELETE FROM users WHERE id = #{id}")
  12. public int deleteById(long id);
  13. @Insert("INSERT INTO users(id, firstName, lastName,emailId) " +
  14. " VALUES (#{id}, #{firstName}, #{lastName}, #{emailId})")
  15. public int insert(User user);
  16. @Update("Update users set firstName=#{firstName}, " +
  17. " lastName=#{lastName}, emailId=#{emailId} where id=#{id}")
  18. public int update(User user);
  19. }

创建用户休息控制器

  1. package com.knf.dev.demo.springbootmybatiscrudexample.controller;
  2. import com.knf.dev.demo.springbootmybatiscrudexample.
  3. exception.UserIdAlreadyExistException;
  4. import com.knf.dev.demo.springbootmybatiscrudexample.
  5. exception.UserIdNotFoundException;
  6. import com.knf.dev.demo.springbootmybatiscrudexample.model.User;
  7. import com.knf.dev.demo.springbootmybatiscrudexample.
  8. repository.UserRepository;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.http.ResponseEntity;
  11. import org.springframework.web.bind.annotation.*;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. @RestController
  16. @RequestMapping("/api/v1/")
  17. public class UserController {
  18. @Autowired
  19. private UserRepository userRepository;
  20. // get all users
  21. @GetMapping("/users")
  22. public List<User> getAllUsers()
  23. {
  24. return userRepository.findAll();
  25. }
  26. // create user rest API
  27. @PostMapping("/users")
  28. public User createUser(@RequestBody User user) {
  29. if(userRepository.findById(user.getId())==null) {
  30. int id = userRepository.insert(user);
  31. return userRepository.findById(user.getId());
  32. }else
  33. {
  34. throw new UserIdAlreadyExistException();
  35. }
  36. }
  37. // get user by id rest api
  38. @GetMapping("/users/{id}")
  39. public ResponseEntity<User> getUserById(@PathVariable Long id) {
  40. User user = userRepository.findById(id);
  41. if(user==null)
  42. {
  43. throw new UserIdNotFoundException();
  44. }
  45. return ResponseEntity.ok(user);
  46. }
  47. // update user rest api
  48. @PutMapping("/users/{id}")
  49. public ResponseEntity<User> updateUser(@PathVariable Long id,
  50. @RequestBody User userDetails) {
  51. if(userRepository.update(new User(id, userDetails.getFirstName(),
  52. userDetails.getLastName(), userDetails.getEmailId()))==0)
  53. {
  54. throw new UserIdNotFoundException();
  55. }
  56. return ResponseEntity.ok(userRepository.findById(id));
  57. }
  58. // delete user rest api
  59. @DeleteMapping("/users/{id}")
  60. public ResponseEntity<Map<String, Boolean>> deleteUser
  61. (@PathVariable Long id) {
  62. userRepository.deleteById(id);
  63. Map<String, Boolean> response = new HashMap<>();
  64. response.put("deleted", Boolean.TRUE);
  65. return ResponseEntity.ok(response);
  66. }
  67. }

创建自定义异常

UserIdNotFoundException

  1. package com.knf.dev.demo.springbootmybatiscrudexample.exception;
  2. public class UserIdNotFoundException extends RuntimeException{
  3. public UserIdNotFoundException()
  4. {
  5. super("User Id Not Found");
  6. }
  7. }

UserIdAlreadyExistException

  1. package com.knf.dev.demo.springbootmybatiscrudexample.exception;
  2. public class UserIdAlreadyExistException extends RuntimeException{
  3. public UserIdAlreadyExistException() {
  4. super("User Id Already Exist");
  5. }
  6. }

全局异常处理程序

Spring 支持通过全局异常处理程序 (@ExceptionHandler) 和控制器建议 (@ControllerAdvice) 处理异常。这启用了一种机制,使 ResponseEntity 与 @ExceptionHandler 的类型安全和灵活性一起工作。

  1. package com.knf.dev.demo.springbootmybatiscrudexample.exception;
  2. import org.springframework.http.HttpStatus;
  3. import org.springframework.http.ResponseEntity;
  4. import org.springframework.web.bind.annotation.ControllerAdvice;
  5. import org.springframework.web.bind.annotation.ExceptionHandler;
  6. import org.springframework.web.context.request.WebRequest;
  7. import java.time.LocalDateTime;
  8. @ControllerAdvice
  9. public class GlobalExceptionHandler {
  10. @ExceptionHandler(UserIdNotFoundException.class)
  11. public ResponseEntity<CustomErrorResponse>
  12. globalExceptionHandler(Exception ex, WebRequest request) {
  13. CustomErrorResponse errors = new CustomErrorResponse();
  14. errors.setTimestamp(LocalDateTime.now());
  15. errors.setError(ex.getMessage());
  16. errors.setStatus(HttpStatus.NOT_FOUND.value());
  17. return new ResponseEntity<>(errors, HttpStatus.NOT_FOUND);
  18. }
  19. @ExceptionHandler(UserIdAlreadyExistException.class)
  20. public ResponseEntity<CustomErrorResponse>
  21. globalExceptionHandler2(Exception ex, WebRequest request) {
  22. CustomErrorResponse errors = new CustomErrorResponse();
  23. errors.setTimestamp(LocalDateTime.now());
  24. errors.setError(ex.getMessage());
  25. errors.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
  26. return new ResponseEntity<>
  27. (errors, HttpStatus.INTERNAL_SERVER_ERROR);
  28. }
  29. }

自定义错误响应

  1. package com.knf.dev.demo.springbootmybatiscrudexample.exception;
  2. import com.fasterxml.jackson.annotation.JsonFormat;
  3. import java.time.LocalDateTime;
  4. public class CustomErrorResponse {
  5. @JsonFormat(shape = JsonFormat.Shape.STRING,
  6. pattern = "yyyy-MM-dd hh:mm:ss")
  7. private LocalDateTime timestamp;
  8. private int status;
  9. private String error;
  10. public LocalDateTime getTimestamp()
  11. {
  12. return timestamp;
  13. }
  14. public void setTimestamp(LocalDateTime timestamp)
  15. {
  16. this.timestamp = timestamp;
  17. }
  18. public int getStatus()
  19. {
  20. return status;
  21. }
  22. public void setStatus(int status)
  23. {
  24. this.status = status;
  25. }
  26. public String getError()
  27. {
  28. return error;
  29. }
  30. public void setError(String error)
  31. {
  32. this.error = error;
  33. }
  34. }

Spring Boot 主类

  1. package com.knf.dev.demo.springbootmybatiscrudexample;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class SpringbootMybatisCrudExampleApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.
  8. run(SpringbootMybatisCrudExampleApplication.class, args);
  9. }
  10. }

Spring Boot 应用程序的主类包含一个启动 Spring ApplicationContext 的公共静态 void main() 方法。

#

本地设置

第 1 步:下载或克隆源代码到本地机器。

第 2 步: mvn clean install

第 3 步:运行 Spring Boot 应用程序

  1. mvn spring-boot:run

使用 Postman 测试 API

创建用户:

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBAYWxsd2F5Mg_size_20_color_FFFFFF_t_70_g_se_x_16

获取所有用户:

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBAYWxsd2F5Mg_size_20_color_FFFFFF_t_70_g_se_x_16 1

通过 ID 获取用户:

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBAYWxsd2F5Mg_size_20_color_FFFFFF_t_70_g_se_x_16 2

更新用户:

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBAYWxsd2F5Mg_size_20_color_FFFFFF_t_70_g_se_x_16 3

按 ID 删除用户:

watermark_type_d3F5LXplbmhlaQ_shadow_50_text_Q1NETiBAYWxsd2F5Mg_size_20_color_FFFFFF_t_70_g_se_x_16 4

点击这里下载源代码

发表评论

表情:
评论列表 (有 0 条评论,110人围观)

还没有评论,来说两句吧...

相关阅读