Spring Data JPA - 如何创建查询(8)SpEL表达式

本文介绍如何在Spring Data JPA中使用SpEL表达式来动态构建查询语句,特别是利用#{#entityName}

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

作者简介

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

内容来源:https://docs.spring.io/spring-data/jpa/docs/2.0.9.RELEASE/reference/html/#jpa.query.spel-expressions

从Spring Data JPA 1.4版本开始,支持在@Query定义的查询中使用SpEL模板表达式。在执行查询的时候,这些表达式通过一个事先定义好的变量集合求值。Spring Data JPA支持成为entityName的变量。它的用法是select x from #{#entityName} x。它会将域类型的entityName与给定repository关联起来。entityName按照如下方式处理:如果域类型在@Entity注解上设置了name属性,则使用该属性。否则直接使用域类型的类名。

下例演示了在定义带有查询方法和手工定义查询的repository接口时使用#{#entityName}表达式。

@Entity
public class User {

  @Id
  @GeneratedValue
  Long id;

  String lastname;
}

public interface UserRepository extends JpaRepository<User,Long> {

  @Query("select u from #{#entityName} u where u.lastname = ?1")
  List<User> findByLastname(String lastname);
}

如果要避免在@Query注解中使用真实的实体名称,可以使用#{#entityName}变量。

当然,你可以在查询声明中直接使用User,但这会导致你需要修改查询。引用#{#entityName}还可以实现将User类映射到不同的实体名称上(例如,通过@Entity(name = "MyUser"

另一个#{#entityName}表达式的使用场景是如果你想定义一个通用的repository接口和一个用于具体域类型的指定repository接口。为了避免重复定义具体接口中的自定义查询方法,你可以在通用接口中使用实体名称表达式:

@MappedSuperclass
public abstract class AbstractMappedType {
  …
  String attribute
}

@Entity
public class ConcreteType extends AbstractMappedType { … }

@NoRepositoryBean
public interface MappedTypeRepository<T extends AbstractMappedType>
  extends Repository<T, Long> {

  @Query("select t from #{#entityName} t where t.attribute = ?1")
  List<T> findAllByAttribute(String attribute);
}

public interface ConcreteRepository
  extends MappedTypeRepository<ConcreteType> { … }

在上例中,MappedTypeRepository接口是父接口,应用于扩展了AbstractMappedType的域类型。它定义了一个通用方法findAllByAttribute(…),可在子repository接口调用。如果你在ConcreteRepository调用findByAllAttribute(…),查询将转换为select t from ConcreteType t where t.attribute = ?1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值