簡體   English   中英

Spring Boot JPA查詢生成器以獲取匯總值?

[英]Spring boot jpa query builder for aggregate values?

我想創建可輸出匯總值的可定制查詢。 我知道三種獲取和執行查詢的方法,但是似乎都不足夠。 我要構建的查詢如下所示:

Select max(category), min(price) as minprice from mytable where k='v' group by category

tldr:跳過1和2。

  1. SQL作為字符串
    • private NamedParameterJdbcTemplate template; template.query("select ..." , new MapSqlParameterSource("...", "...") , rs -> {...rs.getString("minprice")...
    • 親:我們可以從查詢中訪問結果
    • 缺點:它沒有使用查詢生成器:我們必須自己構建“ select ...”字符串。
  2. 使用儲存庫
    • public interface MytableRepository extends CrudRepository<Mytable, Integer> { @Query("Select ...") public List<Object[]> findMinMaxPrice(@Param("myParam") String myParam);
    • 優點:我們可以從查詢中訪問結果。
    • 缺點:查詢是硬編碼的
  3. 使用查詢生成器
    • Specification<MyTable> spec = Specifications.<>where((mytable, query, cb) -> { Predicate sql = cb.equal(mytable.get("k"), "v"; return sql; } List<Mytable> result = myJpaSpecificationExecutor.findall(spec);
    • 優點:正在使用查詢生成器
    • 缺點:查詢未使用groupBy。 由於我們的groupBy查詢不是返回Mytable類的Mytable而是聚集值,因此我看不到如何進行這項工作。 我開始從Mytable選擇,所以我認為我需要將其用作Specification類型參數,但這立即意味着結果也應該是MyTable類型,不是嗎?

如何使用具有靈活結果類型的查詢生成器?

您可以考慮使用jOOQ,可以這樣給您帶來盡可能多的靈活性,同時可以將查詢保持在“代碼中”狀態。

它可以從您的數據庫模式生成Java類,您可以使用它使用其DSL進行查詢。 這是一個示例: https : //github.com/benjamin-bader/droptools/blob/master/droptools-example/src/main/java/com/bendb/example/resources/PostsResource.java#L99

這是我上面鏈接的代碼的內容:

    final Record4<Integer, String, OffsetDateTime, String[]> record = create
            .select(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT, arrayAgg(POST_TAG.TAG_NAME))
            .from(BLOG_POST)
            .leftOuterJoin(POST_TAG)
            .on(BLOG_POST.ID.equal(POST_TAG.POST_ID))
            .where(BLOG_POST.ID.equal(id.get()))
            .groupBy(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT)
            .fetchOne();

它看起來有些時髦,但這是生成的內容:

SELECT blog_post.id, blog_post.body, blog_post.created_at, array_agg(post_tag.tags)
FROM blog_post
LEFT JOIN post_tag ON blog_post.id = post_tag.post_id
WHERE blog_post.id = ?
GROUP BY blog_post.id, blog_post.body, blog_post.created_at

您可以看到Java代碼與生成的SQL非常相似,但是由於jOOQ生成的代碼,它仍然是完全類型安全的。 因為它是代碼,所以您可以根據需要動態構建查詢。

這是一個很嚴重的依賴關系,但是如果您的SQL需求是專門的或動態的,它可以為您做很多事情。

我不知道什么級別的靈活性足夠好,但是如果您有一個實體超類,其中包含您感興趣的所有字段,那么可以使用通用存儲庫

public interface MyGenericRepository<E extends MEntity> extends JpaRepository<E,Long> {

  @Query("select e from #{#entityName} e where u.someField = ?1 or e.someOtherField = ?1")
  List<E> findBySomeFieldOrSomeOtherField(String query);
}

文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM