PostgreSQL 教程: 在 Spring Boot 中使用 Spring Data JPA

八月 28, 2024

摘要:在本教程中,我们将了解如何将 PostgreSQL 对接到 Spring Data JPA。

什么是 Spring Boot?

Spring Boot 是一个开源的 Java 框架,用于创建微服务。Spring Boot 提供了一种更快、更容易的方式,来设置、配置和运行简单的应用程序和基于 Web 的应用程序。它是 Spring Framework 和 Embedded Server 的组合。Spring Boot 的主要目标是减少开发、单元测试和集成测试时间,在 Spring Boot 中,不需要 XML 配置。

什么是 Spring Data JPA?

Spring Data JPA 或 JPA 代表 Java 持久性 API,因此在研究之前,我们必须了解 ORM(对象关系映射)。对象关系映射只是将任何 java 对象直接持久化到数据库表中的过程。通常,被持久化的对象的名称将成为表的名称,并且该对象中的每个字段都将成为一个列。在设置完表后,每行对应于应用程序中的一条记录。Hibernate 是 ORM 的一个例子。简而言之,JPA 是接口,而 hibernate 是实现。

Java 持久性 API 提供了,将 java 对象中的数据持久化、读取和管理到数据库中的关系表的规范。JPA 指定了一组规则和准则,用于开发遵循标准的接口。简单来说:JPA 只是实现 ORM 的准则,没有用于实现的底层代码。Spring Data JPA 是 Spring 框架的一部分。Spring 数据仓库抽象的目标是,显著减少为各种持久化存储实现数据访问层所需的样板代码量。Spring Data JPA 不提供 JPA 的实现,它是一个库/框架,在我们的 JPA 提供程序 Hibernate 的上层,添加了一个额外的抽象层。

在 Spring 应用程序中配置 Spring Data JPA 的示例

要求:Spring Tool Suite IDE,Java 8+

在 Spring Tool Suite 中创建 Spring Boot 项目。给出项目名称,并选择添加所需的依赖项(Spring JPA、PostgreSQL 驱动、Spring web),如下面的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>ex</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ex</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

或者,您也可以在创建项目时添加这些依赖项。

application.properties 文件

spring.datasource.url=jdbc:postgresql://localhost:5432/emp
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto = update

项目结构

img

模态层

创建带有一些 JPA 注解的简单 POJO(Plain old java class)。

  • @Entity:此注解定义类可以映射到一个表。
  • @Id:此注解指定该实体的主键。
  • @GeneratedValue:此注解用于指定要使用的主键生成策略。即指示数据库自动为此字段生成一个值。如果未指定策略,则默认使用 AUTO。
package com.example.demo.modal;

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

// @Entity annotation defines that a 
// class can be mapped to a table
@Entity 
public class Employee {
  
    // @ID This annotation specifies 
    // the primary key of the entity.
    @Id 
  
    // @GeneratedValue This annotation 
    // is used to specify the primary 
    // key generation strategy to use
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id;
    private String name;
    private String city;

    public Employee() {
        super();
    }
    public Employee(String name, String city) {
        super();
        this.name = name;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

DAO(数据访问对象)层

  • @Repository:@Repository 注解是满足仓库角色或构造型(也称为数据访问对象或 DAO)的任何类的标记。
  • JpaRepository<Employee, Long> JpaRepository 是 Repository 的特定于 JPA 的扩展。它包含了 CrudRepository 和 PagingAndSortingRepository 的完整 API。因此,它包含用于基本 CRUD 操作的 API,以及用于分页和排序的 API。在这里,我们为 Employee 启用数据库操作。
package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.modal.Employee;

// @Repository is a Spring annotation that
// indicates that the decorated class is a repository.
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    ArrayList<Employee> findAllEmployee();
}

服务层

package com.example.demo.service;
import java.util.ArrayList;
import com.example.demo.modal.Employee;

public interface EmpService {
    ArrayList<Employee> findAllEmployee();
    Employee findAllEmployeeByID(long id);
    void addEmployee();
    void deleteAllData();
}

@Service:此注解与提供某些业务功能的类一起使用。在使用基于注解的配置和 classpath 扫描时,Spring 上下文将自动检测这些类。这里 JPA 仓库有许多预定义的通用方法来执行数据库操作,下面的代码中使用了一些方法。

package com.example.demo.service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.modal.Employee;
import com.example.demo.repository.EmployeeRepository;

//  @Service marks a Java class that performs some service,
//  such as executing business logic, performing 
//  calculations, and calling external APIs.
@Service 
public class EmpServiceImpl implements EmpService {
    @Autowired
    EmployeeRepository employeeRepository;
  
    @Override
    public ArrayList<Employee> findAllEmployee() {
        return (ArrayList<Employee>) employeeRepository.findAll();
    }
  
    @Override
    public Employee findAllEmployeeByID(long id) {
        Optional<Employee> opt = employeeRepository.findById(id);
        if (opt.isPresent())
            return opt.get();
        else
            return null;
    }
  
    @Override
    public void addEmployee() {
        ArrayList<Employee> emp = new ArrayList<Employee>();
        emp.add(new Employee("Lucknow", "Shubham"));
        emp.add(new Employee("Delhi", "Puneet"));
        emp.add(new Employee("Pune", "Abhay"));
        emp.add(new Employee("Noida", "Anurag"));
        for (Employee employee : emp) {
            employeeRepository.save(employee);
        }
    }
  
    @Override
    public void deleteAllData() {
        employeeRepository.deleteAll();
    }
}

控制器层

  • @RestController:这是一个 Spring 注解,用于以声明性方式构建 REST API。RestController 注解应用于类,以将其标记为请求处理程序,Spring 将进行构建,并在运行时提供 RESTful 的 Web 服务。
  • @Autowired:此注解可用于在设置方法上自动装配 bean,就像 @Required 注解、构造函数、属性或具有任意名称和/或多个参数的方法一样。
  • @PostMapping:此注解将 HTTP POST 请求映射到特定的处理程序方法。它是一个组合注释,作为 @RequestMapping(method = RequestMethod.POST) 的一种简写。
  • @GetMapping:此注解是 @RequestMapping 注解的专用版本,作为 @RequestMapping(method = RequestMethod.GET) 的一种简写。在 @Controller 注解的类中,@GetMapping 注解的方法,可处理与给定 URI 表达式匹配的 HTTP GET 请求。
  • @DeleteMapping:此注解将 HTTP DELETE 请求映射到特定的处理程序方法。它是一个组合注释,作为 @RequestMapping(method = RequestMethod.DELETE) 的一种简写。
package com.example.demo.controller;
import java.util.ArrayList;
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.RestController;
import com.example.demo.modal.Employee;
import com.example.demo.service.EmpServiceImpl;

@RestController
public class EmpController {
  
    @Autowired
    EmpServiceImpl empServiceImpl;

    @PostMapping("/")
    public void add() {
        empServiceImpl.addEmployee();
    }

    @GetMapping("/findall")
    public ArrayList<Employee> getAllEmployee() {
        return empServiceImpl.findAllEmployee();
    }

    @GetMapping("/findbyid/{id}")
    public Employee getEmployeeUsingId(@PathVariable long id) {
        return empServiceImpl.findAllEmployeeByID(id);
    }

    @DeleteMapping("/delete")
    public void delete() {
        empServiceImpl.deleteAllData();
    }
}

在 postman 中使用 JPA 显示输出

打开 postman,并逐个点击列出的 API。

保存员工数据:

img

查找所有员工列表:

img img

按 ID 查找员工:

img img

删除所有员工:

img