在本教程中,您将了解如何在 Spring Boot 示例中使用 JPA EntityManager(使用 CRUD 操作和查询方法)。我将向您展示:

  • 在 Spring 引导中访问 JPA 实体管理器的方法
  • 如何使用实体管理器方法:执行SQL查询使用和CRUD操作createQuery
  • 带参数的 JPA 实体管理器查询

内容

  • JPA 实体经理
  • 带有 Spring 引导的 JPA 实体管理器示例
  • 创建和设置 Spring Boot 项目
  • 配置 Spring 数据源、JPA、Hibernate
  • 创建实体
  • 使用 JPA 实体管理器定义存储库
  • JPA EntityManager createQuery
  • 带参数的 JPA 实体管理器查询
  • 用于 CRUD 操作的 JPA 实体管理器方法
  • 使用实体管理器运行 Spring 引导示例
  • 结论
  • 延伸阅读


JPA 实体经理

JPA提供了EntityManager接口,可以帮助我们将实体类持久化到数据库中,管理实体实例的生命周期,例如创建,删除,检索和查询。

Anobject 在持久性上下文的帮助下管理由持久性单元定义的一组实体。在我们的应用程序和持久存储之间,持久性上下文是第一级缓存,用于跟踪所有实体对象的更改,并将更改与数据库同步。使用它们实际上与持久性上下文交互。EntityManagerEntityManager

EntityManager实例(及其配置)由调用的工厂接口创建。一旦关闭或应用程序关闭,其所有内容都将关闭。EntityManagerFactoryEntityManagerFactoryEntityManager

如何访问 JPA 实体管理器?




我们可以在 Spring Bean 中注入一个对象,例如存储库、服务或控制器......使用注释。EntityManager@Autowired

@Repository
public class TutorialRepository {

  @Autowired
  private EntityManager entityManager;

}

Spring Data JPA 将在运行时初始化默认持久性单元。该对象将具有类型并包装休眠的对象。EntityManagerFactoryEntityManagerLocalContainerEntityManagerFactoryBeanSession

另一种访问方法是使用可以指定持久性单元名称、类型(事务范围或扩展范围)和其他属性的注释:EntityManager@PersistenceContext

@Repository
public class TutorialRepository {

  @PersistenceContext
  private EntityManager entityManager;

}

带有 Spring 引导的 JPA 实体管理器示例

–科技:

  • 爪哇 8
  • Spring Boot 2.6.7 (带有 Spring Data JPA)
  • MySQL/PostgreSQL/H2 (嵌入式数据库)
  • Maven 3.8.1

– 项目结构:

springboot jpa mysql id 关键字 springboot jpa entitymanager_spring boot

让我简要解释一下。

 



  • Tutorial数据模型类对应于实体和表教程
  • TutorialRepository用于 CRUD 方法和自定义查找器方法。它将被自动连接。EntityManagerSpringBootJpaEntitymanagerExampleApplication
  • SpringBootJpaEntitymanagerExampleApplication是哪个实现。我们将在这里使用运行查询和其他方法。SpringBootApplicationCommandLineRunnerTutorialRepository
  • application.properties中配置Spring Datasource,JPA和Hibernate。
  • pom.xml包含 Spring Boot 和 MySQL/PostgreSQL/H2 数据库的依赖项。

创建和设置 Spring Boot 项目

使用 Spring Web 工具或您的开发工具(Spring Tool Suite、Eclipse、Intellij)创建 Spring Boot 项目。

然后打开pom.xml并添加以下依赖项:

<!-- web for access H2 database UI -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

我们还需要再添加一个依赖项。
如果你想使用MySQL

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

– 或PostgreSQL

<dependency>
	<groupId>org.postgresql</groupId>
	<artifactId>postgresql</artifactId>
	<scope>runtime</scope>
</dependency>

– 或H2(嵌入式数据库):



<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>

配置 Spring 数据源、JPA、Hibernate

在 src/main/resources 文件夹下,打开 application.properties 并编写这些行。

– 对于 MySQL:

spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update

对于PostgreSQL:

spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
spring.datasource.username= postgres
spring.datasource.password= 123

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
  • spring.datasource.username & spring.datasource.password属性与数据库安装相同。
  • Spring Boot 使用 Hibernate 进行 JPA 实现,我们配置 MySQL 或 PostgreSQLMySQL5InnoDBDialectPostgreSQLDialect
  • spring.jpa.hibernate.ddl-auto用于数据库初始化。我们将值设置为值,以便在数据库中自动创建一个与定义的数据模型对应的表。对模型的任何更改也将触发对表的更新。对于生产,此属性应该是。updatevalidate

– 对于 H2 数据库:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
 
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto= update

spring.h2.console.enabled=true
# default path: h2-console
spring.h2.console.path=/h2-ui
  • spring.datasource.url:用于内存数据库和基于磁盘的数据库。jdbc:h2:mem:[database-name]jdbc:h2:file:[path/database-name]
  • 我们为 H2 数据库配置配置H2Dialect
  • spring.h2.console.enabled=true告诉 Spring 启动 H2 数据库管理工具,您可以在浏览器上访问此工具:http://localhost:8080/h2-console
  • spring.h2.console.path=/h2-ui用于 H2 控制台的 URL,因此默认 url 将更改为。http://localhost:8080/h2-consolehttp://localhost:8080/h2-ui

创建实体

模型包中,我们定义类。Tutorial

教程有四个字段:ID、标题、描述、已发布。

模型/教程.java

package com.bezkoder.spring.jpa.entitymanager.model;

import javax.persistence.*;

@Entity
@Table(name = "tutorials")
public class Tutorial {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  @Column(name = "title")
  private String title;

  @Column(name = "description")
  private String description;

  @Column(name = "published")
  private boolean published;

  public Tutorial() {

  }

  public Tutorial(String title, String description, boolean published) {
    this.title = title;
    this.description = description;
    this.published = published;
  }

  // getters and setters
}

–annotation 表示该类是持久性 Java 类。–annotation 提供映射此实体的表。
@Entity@Table

–注释用于主键。
–注释用于定义主键的生成策略。@Id@GeneratedValue

使用 JPA 实体管理器定义存储库

让我们创建一个存储库来与数据库进行交互。
存储库包中,创建类和注入注释。TutorialRepositoryEntityManager@PersistenceContext

存储库/教程存储库.java

package com.bezkoder.spring.jpa.entitymanager.repository;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;

import org.springframework.stereotype.Repository;

import com.bezkoder.spring.jpa.entitymanager.model.Tutorial;

@Repository
public class TutorialRepository {

  @PersistenceContext
  private EntityManager entityManager;

}

在此类中,我们将使用 EntityManager 和其他用于 CRUD 操作的方法编写查询(带参数)。createQuery

JPA EntityManager createQuery

我们可以使用EntityManager的方法直接在应用程序的业务逻辑中创建动态查询(Java持久性查询语言 - JPQL)。createQuery

public class TutorialRepository {

  @PersistenceContext
  private EntityManager entityManager;

  public List<Tutorial> findAll() {
    TypedQuery<Tutorial> query = entityManager.createQuery("SELECT t FROM Tutorial t", Tutorial.class);
    return query.getResultList();
  }
}

该方法返回教程对象列表,该列表从数据库中教程表中的行映射。findAll()

带参数的 JPA 实体管理器查询

对于方法,我们还可以使用命名参数对参数进行查询。createQuery

public class TutorialRepository {

  @PersistenceContext
  private EntityManager entityManager;

  public List<Tutorial> findByTitleContaining(String title) {
    TypedQuery<Tutorial> query = entityManager.createQuery(
        "SELECT t FROM Tutorial t WHERE LOWER(t.title) LIKE LOWER(CONCAT('%', :title,'%'))",
        Tutorial.class);
    return query.setParameter("title", title).getResultList();
  }

  public List<Tutorial> findByPublished(boolean isPublished) {
    TypedQuery<Tutorial> query = entityManager.createQuery(
        "SELECT t FROM Tutorial t WHERE t.published=:isPublished",
        Tutorial.class);
    return query.setParameter("isPublished", isPublished).getResultList();
  }

  public List<Tutorial> findByTitleAndPublished(String title, boolean isPublished) {
    TypedQuery<Tutorial> query = entityManager.createQuery(
        "SELECT t FROM Tutorial t WHERE LOWER(t.title) LIKE LOWER(CONCAT('%', :title,'%')) AND t.published=:isPublished",
        Tutorial.class);
    return query.setParameter("title", title).setParameter("isPublished", isPublished).getResultList();
  }
}

我们用冒号后跟字符串 (,) 声明参数。实际值将在运行时设置。:title:isPublished

在执行查询之前,使用方法设置一个或多个参数。setParameter

用于 CRUD 操作的 JPA 实体管理器方法

要执行 CRUD(创建、检索、更新、删除)操作,我们可以使用以下 JPA 方法:EntityManager

  • persist:使给定对象受管理和持久化。实体管理器将跟踪其属性更改,以便与数据库同步。
  • find:搜索指定类和主键的实体。如果实体实例包含在持久性上下文中,则会从该上下文返回该实体实例。
  • merge:将给定实体的状态合并到当前持久性上下文中。
  • remove:删除实体实例。
public class TutorialRepository {

  @PersistenceContext
  private EntityManager entityManager;

  @Transactional
  public Tutorial save(Tutorial tutorial) {
    entityManager.persist(tutorial);
    return tutorial;
  }

  public Tutorial findById(long id) {
    Tutorial tutorial = (Tutorial) entityManager.find(Tutorial.class, id);
    return tutorial;
  }

  @Transactional
  public Tutorial update(Tutorial tutorial) {
    entityManager.merge(tutorial);
    return tutorial;
  }

  @Transactional
  public Tutorial deleteById(long id) {
    Tutorial tutorial = findById(id);
    if (tutorial != null) {
      entityManager.remove(tutorial);
    }

    return tutorial;
  }

  @Transactional
  public int deleteAll() {
    Query query = entityManager.createQuery("DELETE FROM Tutorial");
    return query.executeUpdate();
  }
}

对于删除所有实体实例,我们使用方法。createQuery

使用实体管理器运行 Spring 引导示例

让我们打开,我们将在这里实现和自动连接接口来运行 JPA 实体管理器方法。SpringBootJpaEntitymanagerExampleApplication.javaCommandLineRunnerTutorialRepository

package com.bezkoder.spring.jpa.entitymanager;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.bezkoder.spring.jpa.entitymanager.model.Tutorial;
import com.bezkoder.spring.jpa.entitymanager.repository.TutorialRepository;

@SpringBootApplication
public class SpringBootJpaEntitymanagerExampleApplication implements CommandLineRunner {

  @Autowired
  TutorialRepository tutorialRepository;

  public static void main(String[] args) {
    SpringApplication.run(SpringBootJpaEntitymanagerExampleApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    tutorialRepository.deleteAll();

    tutorialRepository.save(new Tutorial("Spring Data", "Tut#1 Description", false));
    tutorialRepository.save(new Tutorial("Java Spring", "Tut#2 Description", false));
    tutorialRepository.save(new Tutorial("Hibernate", "Tut#3 Description", false));
    tutorialRepository.save(new Tutorial("Spring Boot", "Tut#4 Description", false));
    tutorialRepository.save(new Tutorial("Spring Data JPA", "Tut#5 Description", false));
    tutorialRepository.save(new Tutorial("JPA EntityManager", "Tut#6 Description", false));
    tutorialRepository.save(new Tutorial("Spring Security", "Tut#7 Description", false));

    List<Tutorial> tutorials = new ArrayList<>();

    tutorials = tutorialRepository.findAll();
    show(tutorials);
/*
Number of Items: 7
Tutorial [id=1, title=Spring Data, desc=Tut#1 Description, published=false]
Tutorial [id=2, title=Java Spring, desc=Tut#2 Description, published=false]
Tutorial [id=3, title=Hibernate, desc=Tut#3 Description, published=false]
Tutorial [id=4, title=Spring Boot, desc=Tut#4 Description, published=false]
Tutorial [id=5, title=Spring Data JPA, desc=Tut#5 Description, published=false]
Tutorial [id=6, title=JPA EntityManager, desc=Tut#6 Description, published=false]
Tutorial [id=7, title=Spring Security, desc=Tut#7 Description, published=false]
*/

    Tutorial tutorial = tutorialRepository.findById(6);
    System.out.println(tutorial);
/*
Tutorial [id=6, title=JPA EntityManager, desc=Tut#6 Description, published=false]
*/

    Tutorial tut1 = tutorials.get(0);
    tut1.setPublished(true);

    Tutorial tut3 = tutorials.get(2);
    tut3.setPublished(true);

    Tutorial tut5 = tutorials.get(4);
    tut5.setPublished(true);

    tutorialRepository.update(tut1);
    tutorialRepository.update(tut3);
    tutorialRepository.update(tut5);

    tutorials = tutorialRepository.findByTitleContaining("jpa");
    show(tutorials);
/*
Number of Items: 2
Tutorial [id=5, title=Spring Data JPA, desc=Tut#5 Description, published=true]
Tutorial [id=6, title=JPA EntityManager, desc=Tut#6 Description, published=false]
*/

    tutorials = tutorialRepository.findByPublished(true);
    show(tutorials);
/*
Number of Items: 3
Tutorial [id=1, title=Spring Data, desc=Tut#1 Description, published=true]
Tutorial [id=3, title=Hibernate, desc=Tut#3 Description, published=true]
Tutorial [id=5, title=Spring Data JPA, desc=Tut#5 Description, published=true]
*/

    tutorials = tutorialRepository.findByTitleAndPublished("data", true);
    show(tutorials);
/*
Number of Items: 2
Tutorial [id=1, title=Spring Data, desc=Tut#1 Description, published=true]
Tutorial [id=5, title=Spring Data JPA, desc=Tut#5 Description, published=true]
*/

    Tutorial deletedTutorial = tutorialRepository.deleteById(4);
    System.out.println(deletedTutorial);
/*
Tutorial [id=4, title=Spring Boot, desc=Tut#4 Description, published=false]
*/

    tutorials = tutorialRepository.findAll();
    show(tutorials);
/*
Number of Items: 6
Tutorial [id=1, title=Spring Data, desc=Tut#1 Description, published=true]
Tutorial [id=2, title=Java Spring, desc=Tut#2 Description, published=false]
Tutorial [id=3, title=Hibernate, desc=Tut#3 Description, published=true]
Tutorial [id=5, title=Spring Data JPA, desc=Tut#5 Description, published=true]
Tutorial [id=6, title=JPA EntityManager, desc=Tut#6 Description, published=false]
Tutorial [id=7, title=Spring Security, desc=Tut#7 Description, published=false]
*/

    int numberOfDeletedRows = tutorialRepository.deleteAll();
    System.out.println(numberOfDeletedRows);
/*
6
*/

    tutorials = tutorialRepository.findAll();
    show(tutorials);
/*
Number of Items: 0
*/
  }

  private void show(List<Tutorial> tutorials) {
    System.out.println("Number of Items: " + tutorials.size());
    tutorials.forEach(System.out::println);
  }
}

结论

今天我们已经知道如何在 Spring Boot 示例中使用 JPA EntityManager。

您可以使用以下方法继续编写 CRUD Rest API: Spring Boot、Spring Data JPA – Rest CRUD API 示例

如果要为 JPA 存储库编写单元测试:Spring 引导单元测试 带有 @DataJpaTest 的 JPA 存储库

您还可以通过本教程了解: – 如何在 AWS 上部署此 Spring 启动应用程序(免费)。 – dockerize withDocker Compose: Spring Boot and MySQL 示例 – 通过这篇文章 上传 Excel 文件并将数据存储在 MySQL 数据库中的方法– 通过这篇文章上传 CSV 文件并将数据存储在 MySQL 中。

祝你学习愉快!再见。