知識庫 / JPA RSS 訂閱

使用 Spring 的 JPA 指南

JPA,Spring
HongKong
6
03:02 PM · Dec 06 ,2025

1. 概述

本教程演示如何使用 JPA 設置 Spring,並使用 Hibernate 作為持久化提供者。

請參閲這篇文章以瞭解使用 Java 模式化配置和項目的基本 Maven pom 文件設置 Spring 應用程序上下文的逐步介紹。

我們將首先在 Spring Boot 項目中設置 JPA。然後,我們將研究如果我們的項目是標準的 Spring 項目,我們需要進行的全配置。

2. 在 Spring Boot 中使用 JPA

Spring Boot 項目旨在使創建 Spring 應用程序更快、更簡單。 這通過使用各種 Spring 功能的啓動器和自動配置來實現,其中包括 JPA。

2.1. Maven 依賴

為了在 Spring Boot 應用程序中啓用 JPA,我們需要以下 Maven 依賴項: spring-boot-starter spring-boot-starter-data-jpa

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>3.1.0</version>
</dependency>

spring-boot-starter 包含 Spring JPA 的必要自動配置。 spring-boot-starter-jpa 項目引用了所有必要的依賴項,例如 hibernate-core

2.2. 配置

Spring Boot 配置 Hibernate 作為默認的 JPA 提供者,因此除非我們想要自定義它,否則不再需要定義 entityManagerFactory bean。

Spring Boot 還可以自動配置 dataSource bean,具體取決於我們使用的數據庫。對於 H2、HSQLDB 和 Apache Derby 類型的內存數據庫,如果類路徑上存在相應的數據庫依賴,Boot 將自動配置 DataSource。

例如,如果我們要在 Spring Boot JPA 應用中使用 H2 內存數據庫,只需在 pom.xml 文件中添加 h2 依賴即可。

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
</dependency>

這樣一來,我們就不需要定義 dataSource Bean,但如果需要自定義它,我們也可以。

如果想要使用 JPA 與 MySQL 數據庫一起使用,我們需要 mysql-connector-java 依賴。 我們還需要定義 DataSource 配置。

我們可以通過在 @Configuration 類中實現,或者使用標準的 Spring Boot 屬性。

Java 配置與標準 Spring 項目中的配置方式相同:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUsername("mysqluser");
    dataSource.setPassword("mysqlpass");
    dataSource.setUrl(
      "jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true"); 
    
    return dataSource;
}

要使用屬性文件配置數據源,必須設置以 spring.datasource 開頭的屬性:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=mysqluser
spring.datasource.password=mysqlpass
spring.datasource.url=
  jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true

Spring Boot 將自動配置數據源,基於以下屬性。

此外,在 Spring Boot 1 中,默認連接池是 Tomcat,但在 Spring Boot 2 中已更改為 HikariCP

有關在 Spring Boot 中配置 JPA 的更多示例,請參閲 GitHub 項目

正如我們所見,如果使用 Spring Boot,基本 JPA 配置相當簡單。

但是,如果我們的項目是標準的 Spring 項目,則需要使用 Java 或 XML 進行更明確的配置。 我們將在下一部分中重點關注這一點。

3. 在非啓動項目中使用 JPA 與 Java 進行 Spring 配置

要在使用 Spring 項目中的 JPA 時,我們需要設置 EntityManager

這是主要的配置部分,我們可以通過 Spring 工廠 Bean 來完成。它可以是更簡單的 LocalEntityManagerFactoryBean,或者更靈活的 LocalContainerEntityManagerFactoryBean

讓我們看看如何使用後者:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em 
        = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan("com.baeldung.persistence.model");

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaProperties(additionalProperties());

      return em;
   }
   
   // ...

}

我們也需要明確定義我們上面使用的 DataSource Bean:

@Bean
public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");
    dataSource.setUsername( "tutorialuser" );
    dataSource.setPassword( "tutorialmy5ql" );
    return dataSource;
}

配置的最後一部分是額外的 Hibernate 屬性以及 TransactionManagerexceptionTranslation Bean:

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

    return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}

Properties additionalProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
       
    return properties;
}

4. 完全移除 XML

通常,JPA 通過 META-INF/persistence.xml 文件定義持久單元。 從 Spring 3.1 開始,persistence.xml 文件不再必要。 LocalContainerEntityManagerFactoryBean 現在支持 packagesToScan 屬性,其中可以指定掃描用於 @Entity 類 的包。

此文件是我們需要移除的最後一塊 XML。 現在我們可以完全使用 JPA,而無需 XML。

我們通常會在 persistence.xml 文件中指定 JPA 屬性。

或者,我們可以直接將屬性添加到實體管理器工廠 Bean 中:

factoryBean.setJpaProperties(this.additionalProperties());

順便説明一下,如果 Hibernate 是持久性提供者,這裏就是指定 Hibernate 特定的屬性的方式。

5. The Maven Configuration

除了 Spring Core 和持久化依賴項(如在“Spring with Maven”教程中詳細介紹的)外,我們還需要將 JPA 和 Hibernate 定義到項目中,以及 MySQL 連接器。

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>6.5.2.Final</version>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.19</version>
   <scope>runtime</scope>
</dependency>

請注意,MySQL 依賴項此處作為示例包含在內。我們需要一個驅動程序來配置數據源,但任何支持 Hibernate 的數據庫都可以

6. Spring Data JPA 示例項目

讓我們通過一個示例項目來觀察 Spring Data JPA 的實際應用。

6.1. 實體類

首先,讓我們創建一個新的實體類:

@Entity
public class Publishers {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private String location;
    private int journals;
    // constructors, getters and setters
}

在這裏,我們創建了一個名為 Publishers 的實體類,它代表一個數據庫表,字段代表數據庫中的列。在本例中,我們有四個列,其中 id 是主鍵。

6.2. 倉庫 (Repository)

Spring Data JPA 提供倉庫支持,以便在不編寫冗餘代碼的情況下執行各種數據庫操作。 倉庫充當實體和數據庫之間的橋樑。

讓我們創建一個 <em>PublisherRepository</em> 接口:

public interface PublisherRepository extends JpaRepository<Publishers, Integer> {
}

存儲接口繼承了 JpaRepository,該接口提供了各種內置方法,用於數據庫操作。 常見方法包括:

  • save() – 將實體持久化到數據庫
  • findById() – 通過其 id 查找數據庫記錄
  • findAll() – 獲取所有實體
  • findById() – 通過其 id 獲取實體。

此外,Spring Data JPA 允許我們通過遵循特定命名約定來通過方法推導查詢:

public interface PublisherRepository extends JpaRepository<Publishers, Integer> {
    List<Publishers> findAllByLocation(String location);
}

在上述代碼中,我們定義了一個名為 findAllByLocation() 的方法。當該方法在 PublisherRepository 對象上被調用時,它會被解析並轉換為一個 SQL 查詢。 findAllBy 前綴表示查詢的開始,Location 則表示與實體類中 location 字段對應的屬性名稱。

此外,我們還可以使用 @Query 註解來定義自定義查詢:

@Query("SELECT p FROM Publishers p WHERE p.journals > :minJournals AND p.location = :location")
List<Publisher> findPublishersWithMinJournalsInLocation(Integer minJournals,String location);

這裏,我們定義了一個查詢,用於根據特定的期刊數量和位置查找所有出版商

6.3. 服務

此外,我們創建一個服務類來為典型的數據庫操作實現不同的邏輯。

首先,讓我們將 PublisherRepository 注入到服務類中:

@Service
class PublisherService {
    private final PublisherRepository publisherRepository;

    public PublisherService(PublisherRepository publisherRepository) {
        this.publisherRepository = publisherRepository;
    }
    // ...
}

接下來,我們創建一個方法來將出版商記錄插入數據庫中:

public Publishers save(Publishers publishers) {
    return publisherRepository.save(publishers);
}

在這裏,我們使用 save() 方法將實體持久化到數據庫中。它既可以保存新的實體,也可以根據實體是否已存在於數據庫中更新現有實體。

接下來,我們查找所有已保存的出版商:

public List<Publishers> findAll() {
    return publisherRepository.findAll();
}

findAll()方法檢索數據庫中所有出版商的記錄,並將它們作為List返回。

此外,我們根據id查找出版商:

public Publishers findById(int id) {
    return publisherRepository.findById(id)
      .orElseThrow(() -> new RuntimeException("Publisher not found"));
}

上述方法根據提供的 id 從數據庫中檢索出版物記錄。如果未找到與提供的 id 匹配的記錄,則會拋出 RuntimeException

此外,讓我們使用帶有自定義查詢 findPublishersWithMinJournalsLocation() 的倉庫方法。它有助於根據最小期刊數量和位置查找出版商:

List<Publishers> findPublishersWithMinJournalsInLocation(int minJournals, String location) {
    return publisherRepository.findPublishersWithMinJournalsInLocation(minJournals, location);
}

現在我們已經定義了用於不同數據庫操作的方法,就可以在我們的測試類或控制器中使用它們。

7. 結論

在本文中,我們學習瞭如何在 Spring Boot 和標準 Spring 應用中配置 JPA 與 Hibernate。我們還查看了一個 Spring Boot 項目的示例,該項目用於持久化實體以及從數據庫檢索實體。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.