@Query
是 Spring Data JPA 提供的一个注解,用于在 Repository 接口中定义自定义的 SQL 或 JPQL 查询语句。以下是 @Query
注解的详细用法:
-
位置与语法:
@Query
注解应用于 Repository 接口中的某个方法上。- 语法格式通常如下:
@Query("<查询语句>") <返回类型> <方法名>(<参数列表>);
-
查询语句:
-
value
属性:这是@Query
注解的核心,用于指定实际的查询语句。- JPQL查询:
- 如果不设置
nativeQuery = true
,默认情况下,@Query
注解内部的查询语句应遵循 Java Persistence Query Language (JPQL) 规范。JPQL 是一种面向对象的查询语言,它以实体类和它们之间的关系为基础,而不是直接操作数据库表。 - 示例:
@Query("SELECT b FROM Book b WHERE b.price > ?1 AND b.price < ?2") List<Book> findByPriceRange(Long price1, Long price2);
- 在 JPQL 查询中,可以使用占位符(
?1
,?2
, …) 来引用方法参数,并且支持标准的 JPQL 关键字、操作符、聚合函数以及 JOIN 语句等。
- 如果不设置
- JPQL查询:
-
原生SQL查询:
- 当需要使用特定数据库的原生 SQL 语句时,可以通过设置
nativeQuery = true
来启用原生查询模式。 - 示例:
@Query(value = "SELECT name, author, price FROM Book b WHERE b.price > ? AND b.price < ?", nativeQuery = true) List<Book> findByPriceRangeNative(Long price1, Long price2);
- 原生 SQL 查询允许使用具体的数据库方言和特性,但需要注意的是,由于直接使用了数据库表名和字段名,这样的查询可能缺乏数据库迁移的灵活性。
- 当需要使用特定数据库的原生 SQL 语句时,可以通过设置
-
-
参数绑定:
- 方法参数可以被自动映射到查询语句中的占位符。
- 对于复杂查询或者需要明确指定参数名的情况,可以使用
@Param
注解来标记参数并指明其在查询语句中的别名。@Query("SELECT b FROM Book b WHERE b.name LIKE %:searchTerm%") List<Book> findByNameLike(@Param("searchTerm") String searchTerm);
-
结果映射:
- 查询结果可以被映射到不同的形式:
- 简单类型列表:返回查询结果中选定列的列表,如
List<String>
或List<Long>
。 - 实体列表:返回查询结果对应的实体对象列表,如
List<Book>
。 - 构造函数结果映射:使用
new
关键字配合实体类或自定义类的构造函数,将查询结果映射到新对象中。这允许选择部分字段并组合成一个新的数据结构。@Query("SELECT new com.example.AddressSummary(a.addrId, a.addrDetails) FROM Address a WHERE a.id = :id") AddressSummary findAddressSummary(@Param("id") Long id);
- 分页与排序:如果 Repository 继承了
PagingAndSortingRepository
,则可以返回Page
或Slice
类型的结果,同时传递Pageable
参数来控制分页和排序。
- 简单类型列表:返回查询结果中选定列的列表,如
- 查询结果可以被映射到不同的形式:
-
其他特性:
- SPEL 表达式:在
@Query
注解的值中可以使用 Spring Expression Language (SPEL) 表达式来动态构建查询语句的一部分。例如,使用#{#entityName}
可以获取当前 Repository 管理的实体类名。 - 更新与删除:在
@Query
注解中可以定义修改数据的语句,此时需要加上@Modifying
注解来指示这是一个非查询操作。同时,对于更新或删除操作,通常需要在方法上添加@Transactional
注解来确保事务性。
- SPEL 表达式:在
总结来说,@Query
注解为 Spring Data JPA 提供了一种强大而灵活的方式,允许开发者直接在 Repository 接口中定义定制化的查询语句,无论是使用面向对象的 JPQL 还是具体的数据库原生 SQL,并支持多种参数绑定和结果映射策略,以应对各种复杂的查询需求。