使用 Spring Boot 和 MyBatis 构建 REST CRUD API

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

更多相关主题:

使用的技术:

  • 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}

项目目录:

├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─knf
│  │  │          └─dev
│  │  │              └─demo
│  │  │                  └─springbootmybatiscrudexample
│  │  │                      │  SpringbootMybatisCrudExampleApplication.java
│  │  │                      │
│  │  │                      ├─controller
│  │  │                      │      UserController.java
│  │  │                      │
│  │  │                      ├─exception
│  │  │                      │      CustomErrorResponse.java
│  │  │                      │      GlobalExceptionHandler.java
│  │  │                      │      UserIdAlreadyExistException.java
│  │  │                      │      UserIdNotFoundException.java
│  │  │                      │
│  │  │                      ├─model
│  │  │                      │      User.java
│  │  │                      │
│  │  │                      └─repository
│  │  │                              UserRepository.java
│  │  │
│  │  └─resources
│  │          application.properties
│  │          schema.sql

Maven 依赖项(pom.xml)

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

<?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 
            https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.5.4</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.knf.dev.demo</groupId>
   <artifactId>springboot-mybatis-crud-example</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>springboot-mybatis-crud-example</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>11</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.2.0</version>
      </dependency>

      <dependency>
         <groupId>com.h2database</groupId>
         <artifactId>h2</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

数据库设置

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

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

create table users
(
   id integer not null,
   firstName varchar(255) not null,
   lastName varchar(255) not null,
   emailId varchar(255) not null,
   primary key(id)
);

创建用户模型 

package com.knf.dev.demo.springbootmybatiscrudexample.model;

public class User {

    private long id;
    private String firstName;
    private String lastName;
    private String emailId;

    public User() {
    }

    public User(long id,String firstName, 
              String lastName, String emailId) {
        super();
        this.id=id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.emailId = emailId;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }
}

创建用户 MyBatis 存储库 

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

package com.knf.dev.demo.springbootmybatiscrudexample.repository;

import com.knf.dev.demo.springbootmybatiscrudexample.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface UserRepository {

    @Select("select * from users")
    public List<User> findAll();

    @Select("SELECT * FROM users WHERE id = #{id}")
    public User findById(long id);

    @Delete("DELETE FROM users WHERE id = #{id}")
    public int deleteById(long id);

    @Insert("INSERT INTO users(id, firstName, lastName,emailId) " +
         " VALUES (#{id}, #{firstName}, #{lastName}, #{emailId})")
    public int insert(User user);

    @Update("Update users set firstName=#{firstName}, " +
         " lastName=#{lastName}, emailId=#{emailId} where id=#{id}")
    public int update(User user);
}

创建用户休息控制器

package com.knf.dev.demo.springbootmybatiscrudexample.controller;

import com.knf.dev.demo.springbootmybatiscrudexample.
                           exception.UserIdAlreadyExistException;
import com.knf.dev.demo.springbootmybatiscrudexample.
                           exception.UserIdNotFoundException;
import com.knf.dev.demo.springbootmybatiscrudexample.model.User;
import com.knf.dev.demo.springbootmybatiscrudexample.
                           repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    // get all users
    @GetMapping("/users")
    public List<User> getAllUsers()
    {
        return userRepository.findAll();
    }

    // create user rest API
    @PostMapping("/users")
    public User createUser(@RequestBody User user)  {
        if(userRepository.findById(user.getId())==null) {
            int id = userRepository.insert(user);
            return userRepository.findById(user.getId());
        }else
        {
            throw new UserIdAlreadyExistException();
        }

    }

    // get user by id rest api
    @GetMapping("/users/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userRepository.findById(id);
        if(user==null)
        {
            throw new UserIdNotFoundException();
        }
        return ResponseEntity.ok(user);
    }

 // update user rest api
 @PutMapping("/users/{id}")
 public ResponseEntity<User> updateUser(@PathVariable Long id,
             @RequestBody User userDetails) {
  if(userRepository.update(new User(id, userDetails.getFirstName(), 
         userDetails.getLastName(), userDetails.getEmailId()))==0)
            {
                throw new UserIdNotFoundException();
            }

       return ResponseEntity.ok(userRepository.findById(id));
    }

    // delete user rest api
    @DeleteMapping("/users/{id}")
    public ResponseEntity<Map<String, Boolean>> deleteUser
               (@PathVariable Long id) {
        userRepository.deleteById(id);
        Map<String, Boolean> response = new HashMap<>();
        response.put("deleted", Boolean.TRUE);
        return ResponseEntity.ok(response);
    }
}

 

创建自定义异常

UserIdNotFoundException

package com.knf.dev.demo.springbootmybatiscrudexample.exception;

public class UserIdNotFoundException extends RuntimeException{
    public UserIdNotFoundException()
    {
        super("User Id Not Found");
    }
}

 

UserIdAlreadyExistException

package com.knf.dev.demo.springbootmybatiscrudexample.exception;

public class UserIdAlreadyExistException extends RuntimeException{
    public UserIdAlreadyExistException() {
        super("User Id Already Exist");
    }
}

 

全局异常处理程序

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

package com.knf.dev.demo.springbootmybatiscrudexample.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import java.time.LocalDateTime;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UserIdNotFoundException.class)
    public ResponseEntity<CustomErrorResponse> 
        globalExceptionHandler(Exception ex, WebRequest request) {
        CustomErrorResponse errors = new CustomErrorResponse();
        errors.setTimestamp(LocalDateTime.now());
        errors.setError(ex.getMessage());
        errors.setStatus(HttpStatus.NOT_FOUND.value());
        return new ResponseEntity<>(errors, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(UserIdAlreadyExistException.class)
    public ResponseEntity<CustomErrorResponse> 
        globalExceptionHandler2(Exception ex, WebRequest request) {

        CustomErrorResponse errors = new CustomErrorResponse();
        errors.setTimestamp(LocalDateTime.now());
        errors.setError(ex.getMessage());
        errors.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return new ResponseEntity<>
                 (errors, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

 

自定义错误响应

package com.knf.dev.demo.springbootmybatiscrudexample.exception;

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;

public class CustomErrorResponse {

    @JsonFormat(shape = JsonFormat.Shape.STRING, 
                       pattern = "yyyy-MM-dd hh:mm:ss")
    private LocalDateTime timestamp;
    private int status;
    private String error;
    public LocalDateTime getTimestamp()
    {
        return timestamp;
    }
    public void setTimestamp(LocalDateTime timestamp)
    {
        this.timestamp = timestamp;
    }
    public int getStatus()
    {
        return status;
    }
    public void setStatus(int status)
    {
        this.status = status;
    }
    public String getError()
    {
        return error;
    }
    public void setError(String error)
    {
        this.error = error;
    }
}

Spring Boot 主类

package com.knf.dev.demo.springbootmybatiscrudexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootMybatisCrudExampleApplication {

   public static void main(String[] args) {
      SpringApplication.
         run(SpringbootMybatisCrudExampleApplication.class, args);
   }
}

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

本地设置

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

第 2 步: mvn clean install

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

mvn spring-boot:run

使用 Postman 测试 API

创建用户:

 

获取所有用户:

 

通过 ID 获取用户:

更新用户:

 

按 ID 删除用户:

 

点击这里下载源代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值