原文: https://howtodoinjava.com/spring-restful/spring-rest-crud-jpa-example/

学习使用 Spring REST 和 JPA 配置(以 H2 数据库为后端)创建 REST API 以进行分类操作,而无需 Spring boot 自动配置功能。

1. Maven 依赖

在此示例中,我们使用以下模块及其依赖项。

  • spring-webmvc – 用于处理请求
  • spring-data-jpa – 为接口提供了支持针对后端数据存储读取,更新,删除和创建记录的方法。
  • persistence-api – JPA 规范
  • javax.persistence -JPA 实现
  • Hibernate 实体管理器 – 作为实体供体商
  • Jackson – 用于 JSON 支持
  • H2 – 作为数据库

pom.xml

  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.howtodoinjava.rest</groupId>
  6. <artifactId>SpringRestExample</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <name>SpringRestExample</name>
  10. <url>http://maven.apache.org</url>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <spring.version>5.1.6.RELEASE</spring.version>
  14. <maven.compiler.source>1.8</maven.compiler.source>
  15. <maven.compiler.target>1.8</maven.compiler.target>
  16. </properties>
  17. <dependencies>
  18. <!-- spring webmvc -->
  19. <dependency>
  20. <groupId>org.springframework</groupId>
  21. <artifactId>spring-webmvc</artifactId>
  22. <version>${spring.version}</version>
  23. </dependency>
  24. <!-- spring data jpa -->
  25. <dependency>
  26. <groupId>org.springframework.data</groupId>
  27. <artifactId>spring-data-jpa</artifactId>
  28. <version>2.1.6.RELEASE</version>
  29. </dependency>
  30. <!-- persistence api -->
  31. <dependency>
  32. <groupId>javax.persistence</groupId>
  33. <artifactId>persistence-api</artifactId>
  34. <version>1.0.2</version>
  35. </dependency>
  36. <!-- persistence implementation -->
  37. <dependency>
  38. <groupId>org.eclipse.persistence</groupId>
  39. <artifactId>javax.persistence</artifactId>
  40. <version>2.1.0</version>
  41. </dependency>
  42. <!-- entity manager provider -->
  43. <dependency>
  44. <groupId>org.hibernate</groupId>
  45. <artifactId>hibernate-entitymanager</artifactId>
  46. <version>5.4.2.Final</version>
  47. </dependency>
  48. <!-- H2 database -->
  49. <dependency>
  50. <groupId>com.h2database</groupId>
  51. <artifactId>h2</artifactId>
  52. <version>1.4.199</version>
  53. </dependency>
  54. <!-- JSON support -->
  55. <dependency>
  56. <groupId>com.fasterxml.jackson.core</groupId>
  57. <artifactId>jackson-databind</artifactId>
  58. <version>2.9.8</version>
  59. </dependency>
  60. </dependencies>
  61. </project>

2. DispatcherServlet声明

我们已经在web.xml文件中配置了DispatcherServlet,该文件会将传入的请求路由到适当的控制器方法。

web.xml

  1. <!DOCTYPE web-app PUBLIC
  2. "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  3. "http://java.sun.com/dtd/web-app_2_3.dtd" >
  4. <web-app>
  5. <display-name>Employee Management REST APIs</display-name>
  6. <servlet>
  7. <servlet-name>rest</servlet-name>
  8. <servlet-class>
  9. org.springframework.web.servlet.DispatcherServlet
  10. </servlet-class>
  11. <load-on-startup>1</load-on-startup>
  12. </servlet>
  13. <servlet-mapping>
  14. <servlet-name>rest</servlet-name>
  15. <url-pattern>/api/rest/*</url-pattern>
  16. </servlet-mapping>
  17. </web-app>

3. Spring 和 JPA 配置

rest-servlet.xml文件中,我们已经配置了组件扫描和基于注解的配置支持。 随之,我们配置了实体管理器和数据源配置。

rest-servlet.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  3. xmlns:mvc="http://www.springframework.org/schema/mvc"
  4. xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/data/jpa
  11. http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
  12. http://www.springframework.org/schema/tx
  13. http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
  14. http://www.springframework.org/schema/mvc
  15. http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  16. <context:component-scan base-package="com.howtodoinjava.demo" />
  17. <mvc:annotation-driven />
  18. <jpa:repositories base-package="com.howtodoinjava.demo.repository" entity-manager-factory-ref="emf"/>
  19. <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  20. <property name="packagesToScan" value="com.howtodoinjava.demo.model" />
  21. <property name="dataSource" ref="dataSource" />
  22. <property name="jpaProperties">
  23. <props>
  24. <prop key="hibernate.show_sql">true</prop>
  25. <prop key="hibernate.format_sql">true</prop>
  26. <prop key="hibernate.hbm2ddl.auto">create</prop>
  27. <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
  28. </props>
  29. </property>
  30. <property name="persistenceProvider">
  31. <bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
  32. </property>
  33. </bean>
  34. <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource" id="dataSource">
  35. <property name="driverClass" value="org.h2.Driver" />
  36. <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=2" />
  37. </bean>
  38. <tx:annotation-driven transaction-manager="transactionManager" />
  39. <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
  40. <property name="dataSource" ref="dataSource" />
  41. </bean>
  42. </beans>

4. 实体类

我们只有一个实体类,它将保留在数据库中,并将作为 REST API 的响应返回。

  • @Entity – JPA 注解,以使对象准备好存储在基于 JPA 的数据存储区中。
  • @Table – 数据存储中将存储此实体的表的名称。

阅读更多: JPA 2 持久性注解

Employee.java

  1. import java.io.Serializable;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.Table;
  7. @Entity
  8. @Table(name = "tbl_employee")
  9. public class Employee implements Serializable {
  10. private static final long serialVersionUID = 1L;
  11. @Id
  12. @GeneratedValue(strategy = GenerationType.IDENTITY)
  13. private Long id;
  14. private String firstName;
  15. private String lastName;
  16. private String email;
  17. public Employee() {
  18. }
  19. //Getters and setters
  20. @Override
  21. public String toString() {
  22. return "EmployeeVO [id=" + id + ", firstName=" + firstName + ",
  23. lastName=" + lastName + ", email=" + email + "]";
  24. }
  25. }

5. 存储库

我们已将JpaRepository实现创建为EmployeeRepository,它提供了用于对员工实体执行搜索,获取,更新和删除操作的所有默认操作。

EmployeeRepository.java

  1. import org.springframework.data.jpa.repository.JpaRepository;
  2. import org.springframework.stereotype.Repository;
  3. import com.howtodoinjava.demo.model.Employee;
  4. @Repository
  5. public interface EmployeeRepository extends JpaRepository<Employee, Long> {
  6. }

6. REST 控制器

REST 控制器定义了可以调用以对员工资源执行操作的所有 CRUD 方法。

在给定的控制器中,@RestController注解指示方法返回的数据将直接写入响应主体中,而不呈现模板。 其他注解(@GetMapping@PostMapping@PutMapping@DeleteMapping)将 HTTP 请求映射到相应的方法。

EmployeeRESTController.java

  1. import java.util.List;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.http.MediaType;
  4. import org.springframework.web.bind.annotation.DeleteMapping;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. import org.springframework.web.bind.annotation.PostMapping;
  8. import org.springframework.web.bind.annotation.PutMapping;
  9. import org.springframework.web.bind.annotation.RequestBody;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import com.howtodoinjava.demo.model.Employee;
  13. import com.howtodoinjava.demo.repository.EmployeeRepository;
  14. @RestController
  15. @RequestMapping(value = "/employee-management", produces = { MediaType.APPLICATION_JSON_VALUE })
  16. public class EmployeeRESTController
  17. {
  18. @Autowired
  19. private EmployeeRepository repository;
  20. public EmployeeRepository getRepository() {
  21. return repository;
  22. }
  23. public void setRepository(EmployeeRepository repository) {
  24. this.repository = repository;
  25. }
  26. @GetMapping(value = "/employees")
  27. public List<Employee> getAllEmployees() {
  28. return repository.findAll();
  29. }
  30. @PostMapping("/employees")
  31. Employee createOrSaveEmployee(@RequestBody Employee newEmployee) {
  32. return repository.save(newEmployee);
  33. }
  34. @GetMapping("/employees/{id}")
  35. Employee getEmployeeById(@PathVariable Long id) {
  36. return repository.findById(id).get();
  37. }
  38. @PutMapping("/employees/{id}")
  39. Employee updateEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {
  40. return repository.findById(id).map(employee -> {
  41. employee.setFirstName(newEmployee.getFirstName());
  42. employee.setLastName(newEmployee.getLastName());
  43. employee.setEmail(newEmployee.getEmail());
  44. return repository.save(employee);
  45. }).orElseGet(() -> {
  46. newEmployee.setId(id);
  47. return repository.save(newEmployee);
  48. });
  49. }
  50. @DeleteMapping("/employees/{id}")
  51. void deleteEmployee(@PathVariable Long id) {
  52. repository.deleteById(id);
  53. }
  54. }

7. Spring REST CRUD 操作演示

让我们测试一下 API 操作,以验证它们是否有效。

7.1. 创建员工

API Request

  1. HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees
  2. {
  3. "firstName": "lokesh",
  4. "lastName": "gupta",
  5. "email": "abc@gmail.com"
  6. }

API Response

  1. HTTP Response code : 200
  2. {
  3. "id": 1,
  4. "firstName": "lokesh",
  5. "lastName": "gupta",
  6. "email": "abc@gmail.com"
  7. }

创建更多的员工进行测试。

7.2. 获取员工集合

API Request

  1. HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees

API Response

  1. HTTP Response code : 200
  2. [
  3. {
  4. "id": 1,
  5. "firstName": "lokesh",
  6. "lastName": "gupta",
  7. "email": "abc@gmail.com"
  8. },
  9. {
  10. "id": 2,
  11. "firstName": "Amit",
  12. "lastName": "Sharma",
  13. "email": "xyz@gmail.com"
  14. }
  15. ]

7.3. 按编号获取员工

API Request

  1. HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1

API Response

  1. HTTP Response code : 200
  2. {
  3. "id": 1,
  4. "firstName": "lokesh",
  5. "lastName": "gupta",
  6. "email": "abc@gmail.com"
  7. }

7.4. 更新员工

API Request

  1. HTTP PUT : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1
  2. {
  3. "firstName": "Lucky",
  4. "lastName": "Gupta",
  5. "email": "abc@gmail.com"
  6. }

API Response

  1. HTTP Response code : 200
  2. {
  3. "id": 1,
  4. "firstName": "Lucky",
  5. "lastName": "Gupta",
  6. "email": "abc@gmail.com"
  7. }

7.5. 删除员工

API Request

  1. HTTP DELETE : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1

API Response

  1. HTTP Response code : 200

学习愉快!

下载源码