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数据库如下:
