Spring Data JPA - 如何创建查询(11)配置 Fetch-和LoadGraphs

本文介绍Spring Data JPA中@EntityGraph注解的应用,通过示例展示了如何配置实体查询的提取计划,解决关联结构实体的查询性能问题,避免n+1查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者简介

陈喆,现就职于中科院某研究所担任副研究员,专注于工业云平台、MES系统的设计与研发。

内容来源:https://docs.spring.io/spring-data/jpa/docs/2.0.9.RELEASE/reference/html/#jpa.entity-graph

Spring Data JPA支持@EntityGraph注解,并通过@NamedEntityGraph注解引用。你可以使用该注解配置实体查询的提取计划。通过@EntityGraph注解的type属性定义提取的类型(Fetch或Load)。

注:Fetch-是为了解决关联结构实体的查询性能问题,可以实现通过一次查询就获取到需要的所有关联实体,并避免查询的n+1问题(就是如果1个实体对象关联10个实体对象,就会发出1+10个请求)。jpa效率优化对这个问题进行了比较详细的说明。

下例演示例如何定义一个EntityGraph:

@Entity
@NamedEntityGraph(name = "GroupInfo.detail",
  attributeNodes = @NamedAttributeNode("members"))
public class GroupInfo {

  // default fetch mode is lazy.
  @ManyToMany
  List<GroupMember> members = new ArrayList<GroupMember>();

  …
}

下例演示在repository的查询方法上如何引用一个NamedEntityGraph:

@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {

  @EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)
  GroupInfo getByGroupName(String name);

}

也可以使用@EntityGraph定义特定的EntityGraph。给定attributePaths会直接转换成相应的EntityGraph,而无需显式在域类型上添加@NamedEntityGraph:

@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {

  @EntityGraph(attributePaths = { "members" })
  GroupInfo getByGroupName(String name);

}

 

 

### Spring Data JPA 入门教程 #### 创建 Maven 或 Gradle 项目结构 为了开始使用 Spring Data JPA,首先需要设置好开发环境。这通常意味着创建一个新的 Maven 或 Gradle 项目,并添加必要的依赖项来支持 Spring Boot Spring Data JPA 功能。 对于 Maven 用户,在 `pom.xml` 文件中加入如下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 而对于 Gradle 用户,则应在 `build.gradle` 中添加相应的行: ```groovy implementation 'org.springframework.boot:spring-boot-starter-data-jpa' ``` #### 定义实体类 定义一个简单的 Java 类作为持久化对象模型的一部分。例如,可以基于给定的图书类例子[^3] 来构建自己的实体类。注意这里的注解用于指定表名、字段映射以及关系管理等细节。 ```java @Getter @Setter @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer bookId; private String bookName; private Float price; private Date pubdate; @ManyToOne(fetch = FetchType.LAZY) private Author author; } ``` #### 配置数据源 JPA 设置 在应用程序属性文件 (`application.properties`) 中提供连接到目标数据库所需的信息。如果希望简化初期的学习过程,可以选择内存型数据库如 H2 数据库来进行练习,这样就不必担心实际部署中的复杂配置问题[^2]。 ```properties spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect ``` #### 编写 Repository 接口 接下来就是实现 DAO (Data Access Object) 层了。按照所提供的代码片段[^4] ,只需继承自 `JpaRepository<T, ID>` 即可获得一组丰富的 CRUD 方法集合而不需要额外编写任何 SQL 查询语句。 ```java @Repository public interface UserRepository extends JpaRepository<User, String> {} ``` 同样地,针对上面提到过的书籍实体也可以建立对应的仓库接口: ```java public interface BookRepository extends JpaRepository<Book, Integer> {} ``` #### 测试功能 完成上述准备工作之后便可以通过 RESTful API 或者命令行工具 POSTMAN 对服务端点发起请求验证各项操作是否正常工作[^1] 。此外还可以利用内置的支持机制快速执行单元测试而不必真的启动整个应用上下文环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值