Spring Cloud 自定义SQL / DML查询方法
上面的List<Trade> fetchByActionNamedQuery(String action)
示例与Spring Data查询创建命名约定不匹配,因此我们必须将参数化的Spanner SQL查询映射到它。
可以通过以下两种方式之一将方法的SQL查询映射到存储库方法:
namedQueries
属性文件- 使用
@Query
批注
SQL的标记名称与方法参数的@Param
带注释的名称相对应。
自定义SQL查询方法可以接受单个Sort
或Pageable
参数,该参数将应用于SQL中的任何排序或分页:
@Query("SELECT * FROM trades ORDER BY action DESC") List<Trade> sortedTrades(Pageable pageable); @Query("SELECT * FROM trades ORDER BY action DESC LIMIT 1") Trade sortedTopTrade(Pageable pageable);
可以使用:
List<Trade> customSortedTrades = tradeRepository.sortedTrades(PageRequest .of(2, 2, org.springframework.data.domain.Sort.by(Order.asc("id"))));
结果将按“ id”以升序排序。
您的查询方法还可以返回非实体类型:
@Query("SELECT COUNT(1) FROM trades WHERE action = @action") int countByActionQuery(String action); @Query("SELECT EXISTS(SELECT COUNT(1) FROM trades WHERE action = @action)") boolean existsByActionQuery(String action); @Query("SELECT action FROM trades WHERE action = @action LIMIT 1") String getFirstString(@Param("action") String action); @Query("SELECT action FROM trades WHERE action = @action") List<String> getFirstStringList(@Param("action") String action);
DML语句也可以通过查询方法执行,但是唯一可能的返回值是long
,代表受影响的行数。必须在@Query
上设置dmlStatement
布尔设置,以指示查询方法是作为DML语句执行的。
@Query(value = "DELETE FROM trades WHERE action = @action", dmlStatement = true) long deleteByActionQuery(String action);
默认情况下,@EnableSpannerRepositories
上的namedQueriesLocation
属性指向META-INF/spanner-named-queries.properties
文件。您可以通过提供SQL作为“ interface.method”属性的值来在属性文件中指定方法的查询:
Trade.fetchByActionNamedQuery=SELECT * FROM trades WHERE trades.action = @tag0
public interface TradeRepository extends SpannerRepository<Trade, String[]> { // This method uses the query from the properties file instead of one generated based on name. List<Trade> fetchByActionNamedQuery(@Param("tag0") String action); }
使用@Query
批注:
public interface TradeRepository extends SpannerRepository<Trade, String[]> { @Query("SELECT * FROM trades WHERE trades.action = @tag0") List<Trade> fetchByActionNamedQuery(@Param("tag0") String action); }
表名可以直接使用。例如,以上示例中的“交易”。或者,也可以从域类的@Table
批注中解析表名。在这种情况下,查询应引用具有:
个字符之间的完全限定类名的表名::fully.qualified.ClassName:
。
完整的示例如下所示:
@Query("SELECT * FROM :com.example.Trade: WHERE trades.action = @tag0")
List<Trade> fetchByActionNamedQuery(String action);
这允许在自定义查询中使用用SpEL评估的表名。
SpEL也可以用于提供SQL参数:
@Query("SELECT * FROM :com.example.Trade: WHERE trades.action = @tag0
AND price > #{#priceRadius * -1} AND price < #{#priceRadius * 2}")
List<Trade> fetchByActionNamedQuery(String action, Double priceRadius);
更多建议: