Spring Boot & H2 快速指南



Spring Boot & H2 - 概述

什么是H2?

H2 数据库是一个开源的、嵌入式的、内存中的关系数据库管理系统。它是用 Java 编写的,并提供客户端/服务器应用程序。它将数据存储在系统内存中,而不是磁盘。程序关闭后,数据也会丢失。当我们不想持久化数据并对整体功能进行单元测试时,可以使用内存数据库。其他一些流行的内存数据库包括 HSQLDB 或 HyperSQL 数据库和 Apache Derby。H2 是其他嵌入式数据库中最流行的一个。

H2 数据库的优势

以下是 H2 提供的优势列表:

  • 无需配置 - Spring Boot 本身支持 H2,无需额外配置即可配置 H2 数据库。

  • 易于使用 - H2 数据库非常易于使用。

  • 轻量级且快速 - H2 数据库非常轻量级,并且作为内存数据库,速度非常快。

  • 切换配置 - 使用配置文件,您可以轻松地在生产级数据库和内存数据库之间切换。

  • 支持标准 SQL 和 JDBC - H2 数据库支持标准 SQL 的几乎所有功能和 JDBC 的操作。

  • 基于 Web 的控制台 - H2 数据库可以通过其基于 Web 的控制台应用程序进行管理。

配置 H2 数据库

将 H2 数据库添加为 Maven 依赖项,仅此而已。

<dependency>  
   <groupId>com.h2database</groupId>  
   <artifactId>h2</artifactId>  
   <scope>runtime</scope>  
</dependency>  

尽管 Spring Boot 会自动配置 H2 数据库,但我们也可以通过在 application.properties 中指定它们来覆盖默认配置,如下所示。

spring.datasource.url=jdbc:h2:mem:testdb  
spring.datasource.driverClassName=org.h2.Driver  
spring.datasource.username=sa  
spring.datasource.password=  
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true  

持久化 H2 数据

如果需要持久化存储,请在 application.properties 中添加以下配置。

spring.datasource.url=jdbc:h2:file:/data/database
spring.datasource.url=jdbc:h2:C:/data/database    

Spring Boot & H2 - 环境设置

本章将指导您如何准备开发环境以开始使用 Spring Framework。它还将教您如何在设置 Spring Framework 之前在您的机器上设置 JDK、Tomcat 和 Eclipse:

步骤 1 - 设置 Java 开发工具包 (JDK)

Java SE 可免费下载。要下载,点击此处,请下载与您的操作系统兼容的版本。

按照说明下载 Java,然后运行.exe文件以在您的机器上安装 Java。在您的机器上安装 Java 后,您需要设置环境变量以指向正确的安装目录。

为 Windows 2000/XP 设置路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录下:

  • 右键单击“我的电脑”,然后选择“属性”。

  • 在“高级”选项卡下单击“环境变量”按钮。

  • 现在,编辑“Path”变量,并将 Java 可执行文件目录的路径添加到其末尾。例如,如果路径当前设置为C:\Windows\System32,则按如下方式编辑它

C:\Windows\System32;c:\Program Files\java\jdk\bin

为 Windows 95/98/ME 设置路径

假设您已将 Java 安装在 c:\Program Files\java\jdk 目录下:

  • 编辑“C:\autoexec.bat”文件,并在末尾添加以下行:

SET PATH=%PATH%;C:\Program Files\java\jdk\bin

为 Linux、UNIX、Solaris、FreeBSD 设置路径

应将环境变量 PATH 设置为指向 Java 二进制文件已安装的位置。如果您遇到问题,请参考您的 shell 文档。

例如,如果您使用 bash 作为您的 shell,那么您将在.bashrc文件的末尾添加以下行:

export PATH=/path/to/java:$PATH'

或者,如果您使用集成开发环境 (IDE),如 Borland JBuilder、Eclipse、IntelliJ IDEA 或 Sun ONE Studio,则您将必须编译并运行一个简单的程序以确认 IDE 知道您已将 Java 安装在何处。否则,您必须按照 IDE 文档中给出的说明进行正确的设置。

步骤 2 - 设置 Eclipse IDE

本教程中的所有示例都是使用 Eclipse IDE 编写的。因此,我们建议您应该在您的机器上安装最新版本的 Eclipse。

要安装 Eclipse IDE,请从www.eclipse.org/downloads下载最新的 Eclipse 二进制文件。下载安装程序后,将二进制分发版解压缩到方便的位置。例如,在 Windows 上的 C:\eclipse 或 Linux/Unix 上的 /usr/local/eclipse,最后适当设置 PATH 变量。

可以通过在 Windows 机器上执行以下命令来启动 Eclipse,或者您可以简单地双击 eclipse.exe

%C:\eclipse\eclipse.exe 

可以通过在 Unix (Solaris、Linux 等) 机器上执行以下命令来启动 Eclipse:

$/usr/local/eclipse/eclipse

步骤 3 - 设置 m2eclipse

M2Eclipse 是一个 Eclipse 插件,它非常有助于将 Apache Maven 集成到 Eclipse IDE 中。在本教程中,我们使用 Maven 来构建 Spring Boot 项目,并使用 m2eclipse 在 Eclipse 中运行示例。

使用 Eclipse IDE 中的“安装新软件”对话框安装最新的 M2Eclipse 版本,并将其指向此 p2 存储库:https://download.eclipse.org/technology/m2e/releases/latest/

步骤 4 - 设置 Spring Boot 项目

现在,如果一切正常,您可以继续设置您的 Spring Boot。以下是将 Spring Boot 项目下载并安装到您的机器上的简单步骤。

  • 转到 Spring Initializr 链接以创建 Spring Boot 项目,https://start.spring.io/

  • 选择项目为Maven 项目

  • 选择语言为Java

  • 选择 Spring Boot 版本为2.5.3

  • 设置项目元数据 - Group 为com.tutorialspoint,Artifact 为springboot-h2,名称为springboot-h2,描述为Spring Boot 和 H2 数据库的演示项目,包名称为com.tutorialspoint.springboot-h2

  • 选择打包方式为Jar

  • 选择 Java 为11

  • 添加依赖项为Spring Web、Spring Data JPA、H2 数据库和 Spring Boot DevTools

现在单击“生成”按钮以生成项目结构。

Spring Initializr

下载基于 Maven 的 Spring Boot 项目后,将 Maven 项目导入 Eclipse,其余的 Eclipse 将处理。它将下载 Maven 依赖项并构建项目,使其准备好进行进一步开发。

步骤 5 - 用于 REST API 测试的 POSTMAN

POSTMAN 是一个用于测试基于 REST 的 API 的有用工具。要安装 POSTMAN,请从www.postman.com/downloads/下载最新的 POSTMAN 二进制文件。下载可安装文件后,请按照说明进行安装和使用。

Spring Boot & H2 - 项目设置

正如上一章环境设置中所述,我们已将生成的 Spring Boot 项目导入 Eclipse。现在让我们在src/main/java文件夹中创建以下结构。

Project Structure
  • com.tutorialspoint.controller.EmployeeController - 一个基于 REST 的控制器,用于实现基于 REST 的 API。

  • com.tutorialspoint.entity.Employee - 一个表示数据库中相应表的实体类。

  • com.tutorialspoint.repository.EmployeeRepository - 一个存储库接口,用于在数据库上实现 CRUD 操作。

  • com.tutorialspoint.service.EmployeeService - 一个服务类,用于在存储库函数上实现业务操作。

  • com.tutorialspoint.springbooth2.SprintBootH2Application - 一个 Spring Boot 应用程序类。

SprintBootH2Application 类已存在。我们需要创建上述包和相关的类和接口,如下所示:

实体 - Entity.java

以下是 Employee 的默认代码。它表示一个 Employee 表,其中包含 id、name、age 和 email 列。

package com.tutorialspoint.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table
public class Employee {
   @Id
   @Column
   private int id;
   @Column
   private String name;
   @Column
   private int age;
   @Column
   private String email;
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public int getAge() {
      return age;
   }
   public void setAge(int age) {
      this.age = age;
   }
   public String getEmail() {
      return email;
   }
   public void setEmail(String email) {
      this.email = email;
   }
}

存储库 - EmployeeRepository.java

以下是存储库的默认代码,用于在上述实体 Employee 上实现 CRUD 操作。

package com.tutorialspoint.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.tutorialspoint.entity.Employee;
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer>  {
}

服务 - EmployeeService.java

以下是服务的默认代码,用于在存储库函数上实现操作。

package com.tutorialspoint.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.repository.EmployeeRepository;
@Service
public class EmployeeService {
   @Autowired
   EmployeeRepository repository;
   public Employee getEmployeeById(int id) {
      return null;
   }
   public List<Employee> getAllEmployees(){
      return null;
   }
   public void saveOrUpdate(Employee employee) {
   }
   public void deleteEmployeeById(int id) {
   }
}

控制器 - EmployeeController.java

以下是控制器的默认代码,用于实现 REST API。

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return null;
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return null;;
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
   }	
}

应用程序 - SprintBootH2Application.java

以下是应用程序的更新代码,用于使用上述类。

package com.tutorialspoint.sprintbooth2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@ComponentScan({"com.tutorialspoint.controller","com.tutorialspoint.service"})
@EntityScan("com.tutorialspoint.entity")
@EnableJpaRepositories("com.tutorialspoint.repository")
@SpringBootApplication
public class SprintBootH2Application {
   public static void main(String[] args) {
      SpringApplication.run(SprintBootH2Application.class, args);
   }
}

运行/调试配置

在 Eclipse 中创建以下Maven 配置以使用目标spring-boot:run运行 Spring Boot 应用程序。此配置将有助于运行 REST API,我们可以使用 POSTMAN 对其进行测试。

Maven Configuration

Spring Boot & H2 - REST APIs

正如上一章应用程序设置中所述,我们已在 Spring Boot 项目中创建了所需的文件。现在在 POSTMAN 中创建以下集合以测试 REST API。

Postman Structure
  • GET 获取所有员工 - 一个 GET 请求,用于返回所有员工。

  • POST 添加员工 - 一个 POST 请求,用于创建员工。

  • PUT 更新员工 - 一个 PUT 请求,用于更新现有员工。

  • GET 获取员工 - 一个 GET 请求,用于获取由其 ID 标识的员工。

  • DELETE 删除员工 - 一个 DELETE 请求,用于删除由其 ID 标识的员工。

获取所有员工

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL - https://127.0.0.1:8080/emp/employees

添加员工

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

更新员工

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - PUT

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

获取员工

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL - https://127.0.0.1:8080/emp/employee/1 - 其中 1 是员工 ID

删除员工

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - DELETE

  • URL - https://127.0.0.1:8080/emp/employee/1 - 其中 1 是员工 ID

Spring Boot & H2 - 控制台

如同上一章节应用设置中所述,我们已经在Spring Boot项目中创建了必要的文件夹。现在让我们更新位于src/main/resources目录下的application.properties文件和pom.xml文件,以使用不同版本的maven-resources-plugin插件。

application.properties

spring.datasource.url=jdbc:h2:mem:testdb

pom.xml

...
<build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-resources-plugin</artifactId>
         <version>3.1.0</version>
      </plugin>
   </plugins>
</build>
...

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------< com.tutorialspoint:sprint-boot-h2 >------------------
[INFO] Building sprint-boot-h2 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

...
2021-07-24 20:51:11.347  INFO 9760 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer
: Tomcat initialized with port(s): 8080 (http)
...
2021-07-24 20:51:11.840  INFO 9760 --- [  restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration 
: H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
...
2021-07-24 20:51:14.805  INFO 9760 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer
: Tomcat started on port(s): 8080 (http) with context path ''
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,在浏览器中打开localhost:8080/h2-console,然后点击“测试连接”以验证数据库连接。

h2 Console Login

点击“连接”按钮,将出现H2数据库窗口,如下所示:

h2 console

Spring Boot & H2 - 添加记录

现在,让我们更新到目前为止创建的项目,以准备一个完整的添加记录API并进行测试。

更新服务

// Use repository.save() to persist Employee entity in database
public void saveOrUpdate(Employee employee) {
   repository.save(employee);
}

EmployeeService

package com.tutorialspoint.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.repository.EmployeeRepository;
@Service
public class EmployeeService {
   @Autowired
   EmployeeRepository repository;
   public Employee getEmployeeById(int id) {
      return null;
   }
   public List<Employee> getAllEmployees(){
      return null;
   }
   public void saveOrUpdate(Employee employee) {
      repository.save(employee);
   }
   public void deleteEmployeeById(int id) {
   }
}

更新控制器

// Use service.saveOrUpdate() to persist Employee entity in database
@PostMapping("/employee")
public void addEmployee(@RequestBody Employee employee) {
   employeeService.saveOrUpdate(employee);   
}

EmployeeController

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return null;
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return null;;
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);   
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
   }	
}

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
...
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,使用Postman发出POST请求:

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击“发送”按钮,并检查响应状态是否为OK。现在打开H2控制台,使用以下查询验证插入的记录:

Select * from Employee;

它应该显示以下结果:

ID    AGE    EMAIL              NAME  
1     35   [email protected]      Julie

Spring Boot & H2 - 获取记录

现在,让我们更新到目前为止创建的项目,以准备一个完整的获取记录API并进行测试。

更新服务

// Use repository.findById() to get Employee entity by Id
public Employee getEmployeeById(int id) {
   return repository.findById(id).get();
}

EmployeeService

package com.tutorialspoint.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.repository.EmployeeRepository;
@Service
public class EmployeeService {
   @Autowired
   EmployeeRepository repository;
   public Employee getEmployeeById(int id) {
      return repository.findById(id).get();
   }
   public List<Employee> getAllEmployees(){
      return null;
   }
   public void saveOrUpdate(Employee employee) {
      repository.save(employee);
   }
   public void deleteEmployeeById(int id) {
   }
}

更新控制器

// Use service.getEmployeeById() to get Employee entity from database
@GetMapping("/employee/{id}")
public Employee getEmployee(@PathVariable("id") int id) {
   return employeeService.getEmployeeById(id);
}

EmployeeController

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return null;
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return employeeService.getEmployeeById(id);
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);   
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
   }	
}

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
...
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,使用Postman先发出POST请求添加一条记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击“发送”按钮,并检查响应状态是否为OK。现在发出GET请求获取该记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL:https://127.0.0.1:8080/emp/employee/1

点击发送按钮并验证响应。

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

Spring Boot & H2 - 获取所有记录

现在,让我们更新到目前为止创建的项目,以准备一个完整的获取所有记录API并进行测试。

更新服务

// Use repository.findAll() to get all Employee records
public List<Employee> getAllEmployees(){
   List<Employee> employees = new ArrayList<Employee>();
   repository.findAll().forEach(employee -> employees.add(employee));
   return employees;
}

EmployeeService

package com.tutorialspoint.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.repository.EmployeeRepository;
@Service
public class EmployeeService {
   @Autowired
   EmployeeRepository repository;
   public Employee getEmployeeById(int id) {
      return repository.findById(id).get();
   }
   public List<Employee> getAllEmployees(){
      List<Employee> employees = new ArrayList<Employee>();
      repository.findAll().forEach(employee -> employees.add(employee));
      return employees;
   }
   public void saveOrUpdate(Employee employee) {
      repository.save(employee);
   }
   public void deleteEmployeeById(int id) {
   }
}

更新控制器

// Use service.getAllEmployees() to get a list of employees from database
@GetMapping("/employees")
public List<Employee> getAllEmployees(){
   return employeeService.getAllEmployees();
}

EmployeeController

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return employeeService.getAllEmployees();
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return employeeService.getEmployeeById(id);
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);   
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
   }	
}

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
...
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,使用Postman先发出POST请求添加一条记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击“发送”按钮,并检查响应状态是否为OK。现在发出GET请求获取所有记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL - https://127.0.0.1:8080/emp/employees

点击发送按钮并验证响应。

[{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}]   

Spring Boot & H2 - 更新记录

现在,让我们更新到目前为止创建的项目,以准备一个完整的更新记录API并进行测试。

更新控制器

// Use service.saveOrUpdate() to update an employee record
@PutMapping("/employee")
public void updateEmployee(@RequestBody Employee employee) {
   employeeService.saveOrUpdate(employee);
}	

EmployeeController

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return employeeService.getAllEmployees();
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return employeeService.getEmployeeById(id);
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
      employeeService.deleteEmployeeById(id);
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);   
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);
   }	
}

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
...
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,使用Postman先发出POST请求添加一条记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击“发送”按钮,并检查响应状态是否为OK。

现在发出PUT请求更新该记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - PUT

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击发送按钮并验证响应状态是否为OK。

现在发出GET请求获取所有记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL - https://127.0.0.1:8080/emp/employees

点击发送按钮并验证响应。

[{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}]   

Spring Boot & H2 - 删除记录

现在,让我们更新到目前为止创建的项目,以准备一个完整的删除记录API并进行测试。

更新服务

// Use repository.deleteById() to delete an Employee record
public void deleteEmployeeById(int id) {
   repository.deleteById(id);
}

EmployeeService

package com.tutorialspoint.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.repository.EmployeeRepository;
@Service
public class EmployeeService {
   @Autowired
   EmployeeRepository repository;
   public Employee getEmployeeById(int id) {
      return repository.findById(id).get();
   }
   public List<Employee> getAllEmployees(){
      List<Employee> employees = new ArrayList<Employee>();
      repository.findAll().forEach(employee -> employees.add(employee));
      return employees;
   }
   public void saveOrUpdate(Employee employee) {
      repository.save(employee);
   }
   public void deleteEmployeeById(int id) {
      repository.deleteById(id);
   }
}

更新控制器

// Use service.deleteEmployeeById() to delete an employee by id
@DeleteMapping("/employee/{id}")
public void deleteEmployee(@PathVariable("id") int id) {
   employeeService.deleteEmployeeById(id);
}

EmployeeController

package com.tutorialspoint.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.service.EmployeeService;
@RestController
@RequestMapping(path = "/emp")
public class EmployeeController {
   @Autowired
   EmployeeService employeeService;
   @GetMapping("/employees")
   public List<Employee> getAllEmployees(){
      return employeeService.getAllEmployees();
   }
   @GetMapping("/employee/{id}")
   public Employee getEmployee(@PathVariable("id") int id) {
      return employeeService.getEmployeeById(id);
   }
   @DeleteMapping("/employee/{id}")
   public void deleteEmployee(@PathVariable("id") int id) {
      employeeService.deleteEmployeeById(id);
   }
   @PostMapping("/employee")
   public void addEmployee(@RequestBody Employee employee) {
      employeeService.saveOrUpdate(employee);   
   }
   @PutMapping("/employee")
   public void updateEmployee(@RequestBody Employee employee) {
   }	
}

运行应用

在Eclipse中,运行在应用设置期间准备好的员工应用(Employee Application)配置。

Eclipse控制台将显示类似的输出。

[INFO] Scanning for projects...
...
2021-07-24 20:51:14.823  INFO 9760 --- [  restartedMain] c.t.s.SprintBootH2Application
: Started SprintBootH2Application in 7.353 seconds (JVM running for 8.397)

服务器启动并运行后,使用Postman先发出POST请求添加一条记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - POST

  • URL - https://127.0.0.1:8080/emp/employee

  • 正文 - 员工 JSON

{  
   "id": "1",  
   "age": "35",  
   "name": "Julie",  
   "email": "[email protected]"  
}   

点击“发送”按钮,并检查响应状态是否为OK。

现在发出DELETE请求删除该记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - DELETE

  • URL:https://127.0.0.1:8080/emp/employee/1

点击发送按钮并验证响应状态是否为OK。

现在发出GET请求获取所有记录。

在 POSTMAN 中设置以下参数。

  • HTTP 方法 - GET

  • URL - https://127.0.0.1:8080/emp/employees

点击发送按钮并验证响应。

[]

Spring Boot & H2 - 单元测试控制器

如同上一章节,我们已经完成了我们的REST API。现在让我们在src/main/test文件夹中创建以下结构。

Test Structure
  • com.tutorialspoint.controller.EmployeeControllerTest - 一个单元测试类,用于单元测试EmployeeController的所有方法。

  • com.tutorialspoint.repository.EmployeeRepositoryTest - 一个单元测试类,用于单元测试EmployeeRepository的所有方法。

  • com.tutorialspoint.service.EmployeeServiceTest - 一个单元测试类,用于单元测试EmployeeService的所有方法。

SprintBootH2ApplicationTests类已经存在。我们需要创建上述包和相关的类。

EmployeeControllerTest

要测试REST控制器,我们需要以下注解和类:

  • @ExtendWith(SpringExtension.class) - 使用SpringExtension类标记该类作为测试用例运行。

  • @SpringBootTest(classes = SprintBootH2Application.class) - 配置Spring Boot应用程序。

  • @AutoConfigureMockMvc - 自动配置MockMvc以模拟HTTP请求和响应。

  • @Autowired private MockMvc mvc; - 用于测试的MockMvc对象。

  • @MockBean private EmployeeController employeeController - 要测试的EmployeeController模拟对象。

以下是EmployeeControllerTest的完整代码。

package com.tutorialspoint.controller;
import static org.hamcrest.core.Is.is;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.sprintbooth2.SprintBootH2Application;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = SprintBootH2Application.class)
@AutoConfigureMockMvc
public class EmployeeControllerTest {
   @Autowired
   private MockMvc mvc;
   @MockBean
   private EmployeeController employeeController;
   @Test
   public void testGetAllEmployees() throws Exception {
      Employee employee = getEmployee();
      List<Employee> employees = new ArrayList<>();
      employees.add(employee);
      given(employeeController.getAllEmployees()).willReturn(employees);
      mvc.perform(get("/emp/employees/").contentType(APPLICATION_JSON)).andExpect(status().isOk())
         .andExpect(jsonPath("$[0].name", is(employee.getName())));
   }
   @Test
   public void testGetEmployee() throws Exception {
      Employee employee = getEmployee();
      given(employeeController.getEmployee(1)).willReturn(employee);
      mvc.perform(get("/emp/employee/" + employee.getId()).contentType(APPLICATION_JSON)).andExpect(status().isOk())
         .andExpect(jsonPath("name", is(employee.getName())));
   }
   @Test
   public void testDeleteEmployee() throws Exception {
      Employee employee = getEmployee();
      doNothing().when(employeeController).deleteEmployee(1);
      mvc.perform(delete("/emp/employee/" + employee.getId()).contentType(APPLICATION_JSON))
         .andExpect(status().isOk()).andReturn();
   }
   @Test
   public void testAddEmployee() throws Exception {
      Employee employee = getEmployee();
      doNothing().when(employeeController).addEmployee(employee);
      mvc.perform(post("/emp/employee/").content(asJson(employee)).contentType(APPLICATION_JSON))
         .andExpect(status().isOk()).andReturn();
   }
   @Test
   public void testUpdateEmployee() throws Exception {
      Employee employee = getEmployee();
      doNothing().when(employeeController).updateEmployee(employee);
      mvc.perform(put("/emp/employee/").content(asJson(employee)).contentType(APPLICATION_JSON))
         .andExpect(status().isOk()).andReturn();
   }
   private Employee getEmployee() {
      Employee employee = new Employee();
      employee.setId(1);
      employee.setName("Mahesh");
      employee.setAge(30);
      employee.setEmail("[email protected]");
      return employee;
   }
   private static String asJson(final Object obj) {
      try {
         return new ObjectMapper().writeValueAsString(obj);
      } catch (Exception e) {
         throw new RuntimeException(e);
      }
   }
}

运行测试用例。

在Eclipse中右键单击该文件,然后选择运行JUnit测试,并验证结果。

Controller Test Result

Spring Boot & H2 - 单元测试服务

要测试服务,我们需要以下注解和类:

  • @ExtendWith(SpringExtension.class) - 使用SpringExtension类标记该类作为测试用例运行。

  • @SpringBootTest(classes = SprintBootH2Application.class) - 配置Spring Boot应用程序。

  • @MockBean private EmployeeService employeeService - 要测试的EmployeeService模拟对象。

以下是EmployeeServiceTest的完整代码。

package com.tutorialspoint.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.sprintbooth2.SprintBootH2Application;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = SprintBootH2Application.class)
public class EmployeeServiceTest {
   @MockBean
   private EmployeeService employeeService;
   @Test
   public void testGetAllEmployees() throws Exception {
      Employee employee = getEmployee();
      List<Employee> employees = new ArrayList<>();
      employees.add(employee);
      given(employeeService.getAllEmployees()).willReturn(employees);
      List<Employee> result = employeeService.getAllEmployees();
      assertEquals(result.size(), 1);
   }
   @Test
   public void testGetEmployee() throws Exception {
      Employee employee = getEmployee();
      given(employeeService.getEmployeeById(1)).willReturn(employee);
      Employee result = employeeService.getEmployeeById(1);
      assertEquals(result.getId(), 1);	
   }
   @Test
   public void testDeleteEmployee() throws Exception {
      doNothing().when(employeeService).deleteEmployeeById(1);
      employeeService.deleteEmployeeById(1);
      assertTrue(true);
   }
   @Test
   public void testSaveOrUpdateEmployee() throws Exception {
      Employee employee = getEmployee();
      doNothing().when(employeeService).saveOrUpdate(employee);	
      employeeService.saveOrUpdate(employee);
      assertTrue(true);
   }
   private Employee getEmployee() {
      Employee employee = new Employee();
      employee.setId(1);
      employee.setName("Mahesh");
      employee.setAge(30);
      employee.setEmail("[email protected]");
      return employee;
   }
}

运行测试用例。

在Eclipse中右键单击该文件,然后选择运行JUnit测试,并验证结果。

Service Test Result

Spring Boot & H2 - 单元测试仓库

要测试存储库,我们需要以下注解和类:

  • @ExtendWith(SpringExtension.class) - 使用SpringExtension类标记该类作为测试用例运行。

  • @SpringBootTest(classes = SprintBootH2Application.class) - 配置Spring Boot应用程序。

  • @Transactional - 标记存储库以使其能够执行CRUD操作。

  • @Autowired private EmployeeRepository employeeRepository - 要测试的EmployeeRepository对象。

以下是EmployeeRepositoryTest的完整代码。

package com.tutorialspoint.repository;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.tutorialspoint.entity.Employee;
import com.tutorialspoint.sprintbooth2.SprintBootH2Application;
@ExtendWith(SpringExtension.class)
@Transactional
@SpringBootTest(classes = SprintBootH2Application.class)
public class EmployeeRepositoryTest {
   @Autowired
   private EmployeeRepository employeeRepository;
   @Test
   public void testFindById() {
      Employee employee = getEmployee();	     
      employeeRepository.save(employee);
      Employee result = employeeRepository.findById(employee.getId()).get();
      assertEquals(employee.getId(), result.getId());	     
   }
   @Test
   public void testFindAll() {
      Employee employee = getEmployee();
      employeeRepository.save(employee);
      List<Employee> result = new ArrayList<>();
      employeeRepository.findAll().forEach(e -> result.add(e));
      assertEquals(result.size(), 1);	     
   }
   @Test
   public void testSave() {
      Employee employee = getEmployee();
      employeeRepository.save(employee);
      Employee found = employeeRepository.findById(employee.getId()).get();
      assertEquals(employee.getId(), found.getId());	     
   }
   @Test
   public void testDeleteById() {
      Employee employee = getEmployee();
      employeeRepository.save(employee);
      employeeRepository.deleteById(employee.getId());
      List<Employee> result = new ArrayList<>();
      employeeRepository.findAll().forEach(e -> result.add(e));
      assertEquals(result.size(), 0);
   }
   private Employee getEmployee() {
      Employee employee = new Employee();
      employee.setId(1);
      employee.setName("Mahesh");
      employee.setAge(30);
      employee.setEmail("[email protected]");
      return employee;
   }
}

运行测试用例。

在Eclipse中右键单击该文件,然后选择运行JUnit测试,并验证结果。

Repository Test Result
广告