使用 JPA 配置的 Spring REST CRUD 示例

使用 JPA 配置的 Spring REST CRUD 示例

原文: 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

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.howtodoinjava.rest</groupId>
	<artifactId>SpringRestExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>SpringRestExample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>5.1.6.RELEASE</spring.version>
		<maven.compiler.source>1.8</maven.compiler.source>
    	<maven.compiler.target>1.8</maven.compiler.target>
	</properties>

	<dependencies>
		<!-- spring webmvc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- spring data jpa -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>2.1.6.RELEASE</version>
		</dependency>

		<!-- persistence api -->
		<dependency>
			<groupId>javax.persistence</groupId>
			<artifactId>persistence-api</artifactId>
			<version>1.0.2</version>
		</dependency>

		<!-- persistence implementation -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>javax.persistence</artifactId>
			<version>2.1.0</version>
		</dependency>

		<!-- entity manager provider -->
		<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.2.Final</version>
        </dependency>

        <!-- H2 database -->
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>1.4.199</version> 
		</dependency>

		<!-- JSON support -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.8</version>
		</dependency>
	</dependencies>
</project>

2. DispatcherServlet声明

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

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Employee Management REST APIs</display-name>

	<servlet>
		<servlet-name>rest</servlet-name> 
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>rest</servlet-name>
		<url-pattern>/api/rest/*</url-pattern>
	</servlet-mapping>

</web-app>

3. Spring 和 JPA 配置

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

rest-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<context:component-scan base-package="com.howtodoinjava.demo" />
	<mvc:annotation-driven />
	<jpa:repositories base-package="com.howtodoinjava.demo.repository" entity-manager-factory-ref="emf"/>

	<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
	    <property name="packagesToScan" value="com.howtodoinjava.demo.model" />
	    <property name="dataSource" ref="dataSource" />

	    <property name="jpaProperties">
	        <props>
	            <prop key="hibernate.show_sql">true</prop>
	            <prop key="hibernate.format_sql">true</prop>
	            <prop key="hibernate.hbm2ddl.auto">create</prop>
	            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
	        </props>
	    </property>

	    <property name="persistenceProvider">
	        <bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
	    </property>

	</bean>

	<bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource" id="dataSource">
        <property name="driverClass" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;TRACE_LEVEL_SYSTEM_OUT=2" />
    </bean>

	<tx:annotation-driven transaction-manager="transactionManager" />

	<bean class="org.springframework.orm.jpa.JpaTransactionManager"  id="transactionManager">
	    <property name="dataSource" ref="dataSource" />
	</bean>
</beans>

4. 实体类

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

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

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

Employee.java

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_employee")
public class Employee implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	private String firstName;

	private String lastName;

	private String email;

	public Employee() {
	}

	//Getters and setters

	@Override
	public String toString() {
		return "EmployeeVO [id=" + id + ", firstName=" + firstName + ", 
				lastName=" + lastName + ", email=" + email	+ "]";
	}
}

5. 存储库

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

EmployeeRepository.java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.howtodoinjava.demo.model.Employee;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

}

6. REST 控制器

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

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

EmployeeRESTController.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
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.howtodoinjava.demo.model.Employee;
import com.howtodoinjava.demo.repository.EmployeeRepository;

@RestController
@RequestMapping(value = "/employee-management", produces = { MediaType.APPLICATION_JSON_VALUE })
public class EmployeeRESTController 
{
	@Autowired
	private EmployeeRepository repository;

	public EmployeeRepository getRepository() {
		return repository;
	}

	public void setRepository(EmployeeRepository repository) {
		this.repository = repository;
	}

	@GetMapping(value = "/employees")
	public List<Employee> getAllEmployees() {
		return repository.findAll();
	}

	@PostMapping("/employees")
	Employee createOrSaveEmployee(@RequestBody Employee newEmployee) {
		return repository.save(newEmployee);
	}

	@GetMapping("/employees/{id}")
	Employee getEmployeeById(@PathVariable Long id) {
		return repository.findById(id).get();
	}

	@PutMapping("/employees/{id}")
	Employee updateEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {

		return repository.findById(id).map(employee -> {
			employee.setFirstName(newEmployee.getFirstName());
			employee.setLastName(newEmployee.getLastName());
			employee.setEmail(newEmployee.getEmail());
			return repository.save(employee);
		}).orElseGet(() -> {
			newEmployee.setId(id);
			return repository.save(newEmployee);
		});
	}

	@DeleteMapping("/employees/{id}")
	void deleteEmployee(@PathVariable Long id) {
		repository.deleteById(id);
	}
}

7. Spring REST CRUD 操作演示

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

7.1. 创建员工

API Request

HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees

{
    "firstName": "lokesh",
    "lastName": "gupta",
    "email": "abc@gmail.com"
}

API Response

HTTP Response code : 200

{
	"id": 1,
	"firstName": "lokesh",
	"lastName": "gupta",
	"email": "abc@gmail.com"
}

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

7.2. 获取员工集合

API Request

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

API Response

HTTP Response code : 200

[
	{
		"id": 1,
		"firstName": "lokesh",
		"lastName": "gupta",
		"email": "abc@gmail.com"
	},
	{
		"id": 2,
		"firstName": "Amit",
		"lastName": "Sharma",
		"email": "xyz@gmail.com"
	}
]

7.3. 按编号获取员工

API Request

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

API Response

HTTP Response code : 200

{
	"id": 1,
	"firstName": "lokesh",
	"lastName": "gupta",
	"email": "abc@gmail.com"
}

7.4. 更新员工

API Request

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

{
    "firstName": "Lucky",
    "lastName": "Gupta",
    "email": "abc@gmail.com"
}

API Response

HTTP Response code : 200

{
	"id": 1,
	"firstName": "Lucky",
	"lastName": "Gupta",
	"email": "abc@gmail.com"
}

7.5. 删除员工

API Request

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

API Response

HTTP Response code : 200

学习愉快!

下载源码