Spring Boot JpaRepository 示例
Spring Boot建立在 Spring 之上,包含 Spring 的所有功能。由于其快速的生产就绪环境,使开发人员能够直接专注于逻辑,而不必费力配置和设置,因此如今它正成为开发人员的最爱。Spring Boot 是一个基于微服务的框架,在其中创建生产就绪的应用程序只需很少的时间。以下是 Spring Boot 的一些功能:
- 它可以避免 Spring 中繁重的 XML 配置。
- 它提供了 REST 端点的轻松维护和创建。
- 它包括一个嵌入式的 Tomcat 服务器。
- 部署很简单,war和jar文件可以轻松地部署在Tomcat服务器中。
有关更多信息,请参阅本文:Spring Boot 简介。在本文中,我们将讨论如何使用JpaRepository来管理 Spring Boot 应用程序中的数据。
Jpa存储库
JpaRepository 是 Repository 的一个JPA(Java 持久性 API)特定扩展。它包含CrudRepository 和 PagingAndSortingRepository的完整 API 。因此,它包含用于基本 CRUD 操作的 API 以及用于分页和排序的 API。
句法:
public interface JpaRepository<T,ID> extends PagingAndSortingRepository<T,ID>, QueryByExampleExecutor<T>
这里:
- T:存储库管理的域类型(通常是实体/模型类名)
- ID:存储库管理的实体的 id 类型(通常是在实体/模型类中创建的 @Id 的包装类)
插图:
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
方法
JpaRepository 中的一些最重要的方法如下
方法 1:saveAll():
保存所有给定的实体。
句法:
<S extends T> List<S> saveAll(Iterable<S> entities)
参数:实体,注意它们不能为空,也不能包含空。
返回类型:已保存的实体;永远不会为空。返回的 Iterable 将与作为参数传递的 Iterable 具有相同的大小。
抛出异常:如果给定的实体或其某个实体为空,则会抛出IllegalArgumentException 。
方法 2:getById():
返回具有给定标识符的实体的引用。根据 JPA 持久性提供程序的实现方式,这很可能始终返回一个实例并在首次访问时抛出 EntityNotFoundException。其中一些会立即拒绝无效标识符。
句法:
T getById(ID id)
参数:id – 不能为空。
返回类型:对具有给定标识符的实体的引用。
方法 3:flush():
刷新数据库中所有待处理的更改。
句法:
void flush()
方法 4:saveAndFlush():
保存实体并立即刷新更改。
句法:
<S extends T> S saveAndFlush(S entity)
参数:要保存的实体。不能为空。
返回类型:已保存的实体
方法 5:deleteAllInBatch():
批量删除给定实体,这意味着它将创建单个查询。此类操作会导致 JPA 一级缓存和数据库不同步。在调用此方法之前,请考虑刷新 EntityManager。
句法:
void deleteAllInBatch(Iterable<T> entities)
参数:要删除的实体,不能为空。
实现:
让我们考虑一个使用 JpaRepository 管理 Department 实体的 Spring Boot 应用程序。数据保存在 H2 数据库中。我们使用 RESTful 控制器。
步骤1:使用IntelliJ IDEA创建Spring Boot项目,创建一个Spring Boot项目。
第 2 步:添加以下依赖项
- Spring Web
- H2 Database
- Lombok
- Spring Data JPA
示例:这是pom.xml文件的完整代码。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Model version -->
<modelVersion>4.0.0</modelVersion>
<!-- Parent configuration for Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- Project metadata -->
<groupId>com.amiya</groupId>
<artifactId>Spring-Boot-Demo-Project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Spring-Boot-Demo-Project</name>
<description>Demo project for Spring Boot</description>
<!-- Java version property -->
<properties>
<java.version>17</java.version>
</properties>
<!-- Dependencies required for the project -->
<dependencies>
<!-- Spring Boot Starter Web: To build web applications -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA: To work with JPA for data access -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Boot Starter Validation: For Jakarta EE bean validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- H2 Database: In-memory database for development and testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok: To reduce boilerplate code in Java classes -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<!-- Build configuration -->
<build>
<plugins>
<!-- Spring Boot Maven Plugin: To package the application as a jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<!-- Exclude Lombok from the final build -->
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
步骤 3:创建下面列出的 4 个包,并在这些包中创建一些类和接口,如下图所示
- entity
- repository
- service
- controller
注意:
- 绿色圆形图标“I”按钮是界面
- 蓝色圆形图标“C”按钮属于类
步骤 4:实体包内部
在 Department.java 文件中创建一个简单的POJO 类。
package com.amiya.springbootdemoproject.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Represents a Department entity in the application.
*/
@Entity
@Data // Generates getters, setters, toString, equals, and hashCode methods.
@NoArgsConstructor // Generates a no-args constructor.
@AllArgsConstructor // Generates a constructor with all arguments.
@Builder // Generates a builder pattern for creating instances.
public class Department {
@Id // Specifies the primary key of the entity.
@GeneratedValue(strategy = GenerationType.AUTO) // Auto-generates the primary key value.
private Long departmentId; // Unique identifier for the department.
private String departmentName; // Name of the department.
private String departmentAddress; // Address of the department.
private String departmentCode; // Code representing the department.
}
步骤 5:存储库包内部
创建一个简单的接口,并将该接口命名为 DepartmentRepository。正如我们上面讨论的那样,这个接口将扩展JpaRepository 。
例子:
// Java Program to Illustrate DepartmentRepository File
// Importing necessary packages
package com.amiya.springbootdemoproject.repository;
import com.amiya.springbootdemoproject.entity.Department;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Repository interface for Department entity.
* Provides CRUD operations and custom query methods through JpaRepository.
*/
@Repository // Indicates that this interface is a Spring Data repository.
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
步骤 6:服务包内
在包内创建一个名为DepartmentService 的接口和一个名为DepartmentServiceImpl 的类。
示例 1-A:
// Java Program to Demonstrate DepartmentService File
// Importing required packages
package com.amiya.springbootdemoproject.service;
import com.amiya.springbootdemoproject.entity.Department;
import java.util.List;
/**
* Service interface for Department entity.
* Defines methods for CRUD operations and additional business logic.
*/
public interface DepartmentService {
/**
* Saves a department entity.
* @param department the department to save
* @return the saved department
*/
Department saveDepartment(Department department);
/**
* Fetches the list of all department entities.
* @return a list of departments
*/
List<Department> fetchDepartmentList();
/**
* Updates an existing department entity.
* @param department the department with updated information
* @param departmentId the ID of the department to update
* @return the updated department
*/
Department updateDepartment(Department department, Long departmentId);
/**
* Deletes a department entity by its ID.
* @param departmentId the ID of the department to delete
*/
void deleteDepartmentById(Long departmentId);
}
示例 1-B:
// Java Program to Illustrate DepartmentServiceImpl File
package com.amiya.springbootdemoproject.service;
import com.amiya.springbootdemoproject.entity.Department;
import com.amiya.springbootdemoproject.repository.DepartmentRepository;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Implementation of DepartmentService.
* Provides business logic for handling department-related operations.
*/
@Service // Marks this class as a Spring service component.
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentRepository departmentRepository; // Injects the DepartmentRepository dependency.
@Override
public Department saveDepartment(Department department) {
// Saves and returns the department entity.
return departmentRepository.save(department);
}
@Override
public List<Department> fetchDepartmentList() {
// Retrieves and returns a list of all department entities.
return (List<Department>) departmentRepository.findAll();
}
@Override
public Department updateDepartment(Department department, Long departmentId) {
// Finds the existing department by ID.
Department depDB = departmentRepository.findById(departmentId).get();
// Updates fields if they are not null or empty.
if (Objects.nonNull(department.getDepartmentName()) && !"".equalsIgnoreCase(department.getDepartmentName())) {
depDB.setDepartmentName(department.getDepartmentName());
}
if (Objects.nonNull(department.getDepartmentAddress()) && !"".equalsIgnoreCase(department.getDepartmentAddress())) {
depDB.setDepartmentAddress(department.getDepartmentAddress());
}
if (Objects.nonNull(department.getDepartmentCode()) && !"".equalsIgnoreCase(department.getDepartmentCode())) {
depDB.setDepartmentCode(department.getDepartmentCode());
}
// Saves and returns the updated department entity.
return departmentRepository.save(depDB);
}
@Override
public void deleteDepartmentById(Long departmentId) {
// Deletes the department entity by its ID.
departmentRepository.deleteById(departmentId);
}
}
步骤 7:控制器包装内部
在包内创建一个名为DepartmentController 的类。
// Java Program to Demonstrate DepartmentController File
package com.amiya.springbootdemoproject.controller;
import com.amiya.springbootdemoproject.entity.Department;
import com.amiya.springbootdemoproject.service.DepartmentService;
import java.util.List;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* REST controller for managing Department entities.
* Handles HTTP requests and routes them to the appropriate service methods.
*/
@RestController // Marks this class as a RESTful controller.
public class DepartmentController {
@Autowired
private DepartmentService departmentService; // Injects the DepartmentService dependency.
/**
* Handles POST requests to save a new department.
* @param department the department entity to be saved
* @return the saved department entity
*/
@PostMapping("/departments")
public Department saveDepartment(@Valid @RequestBody Department department) {
return departmentService.saveDepartment(department);
}
/**
* Handles GET requests to fetch the list of all departments.
* @return a list of department entities
*/
@GetMapping("/departments")
public List<Department> fetchDepartmentList() {
return departmentService.fetchDepartmentList();
}
/**
* Handles PUT requests to update an existing department.
* @param department the department entity with updated information
* @param departmentId the ID of the department to be updated
* @return the updated department entity
*/
@PutMapping("/departments/{id}")
public Department updateDepartment(@RequestBody Department department, @PathVariable("id") Long departmentId) {
return departmentService.updateDepartment(department, departmentId);
}
/**
* Handles DELETE requests to remove a department by ID.
* @param departmentId the ID of the department to be deleted
* @return a success message
*/
@DeleteMapping("/departments/{id}")
public String deleteDepartmentById(@PathVariable("id") Long departmentId) {
departmentService.deleteDepartmentById(departmentId);
return "Deleted Successfully";
}
}
步骤 8:下面是 application.properties 文件的代码
server.port=8082 # H2 Database spring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:dcbapp spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
现在运行您的应用程序,让我们在 Postman 中测试端点并参考我们的 H2 数据库。
在 Postman 中测试端点
端点 1: POST – http://localhost:8082/departments/
端点 2: GET – http://localhost:8082/departments/
端点 3: PUT – http://localhost:8082/departments/1
端点 4:删除 – http://localhost:8082/departments/1
H2数据库如下: