簡體   English   中英

如何在 jOOQ 中轉換“to_json()”PostgreSQL function?

[英]How to convert “to_json()” PostgreSQL function in jOOQ?

我正在嘗試將以下 PostgreSQL 查詢轉換為 jOOQ,但似乎找不到解決此問題的適當方法。 這是查詢:

SELECT b.book_id AS b_id, b.title, b.price, b.amount, b.is_deleted,
to_json(array_agg(DISTINCT aut.*)) as authors, 
to_json(array_agg(DISTINCT cat.*)) as categories 
FROM book b 
LEFT JOIN author_book AS ab ON b.book_id = ab.book_id
LEFT JOIN author AS aut ON ab.author_id = aut.author_id
LEFT JOIN category_book AS cb ON b.book_id = cb.book_id
LEFT JOIN category AS cat ON cb.category_id = cat.category_id
GROUP BY b_id ORDER BY b_id ASC;

到目前為止,這是我在 jOOQ 中提出的:

    dslContext
   .select(BOOK.BOOK_ID, BOOK.TITLE, BOOK.PRICE, BOOK.AMOUNT, BOOK.IS_DELETED, 
           DSL.val(DSL.jsonArray(DSL.arrayAggDistinct(AUTHOR.AUTHOR_ID), 
                                 DSL.arrayAggDistinct(AUTHOR.FIRST_NAME),
                                DSL.arrayAggDistinct(AUTHOR.LAST_NAME))
               ).cast(SQLDataType.JSON),                    
        DSL.val(DSL.jsonArray(DSL.arrayAggDistinct(CATEGORY.CATEGORY_ID), 
                              DSL.arrayAggDistinct(CATEGORY.NAME), 
                              DSL.arrayAggDistinct(CATEGORY.IS_DELETED))
            ).cast(SQLDataType.JSON)
    ).from(BOOK
            .leftJoin(AUTHOR_BOOK).on(BOOK.BOOK_ID.eq(AUTHOR_BOOK.BOOK_ID))
            .leftJoin(AUTHOR).on(AUTHOR_BOOK.AUTHOR_ID.eq(AUTHOR.AUTHOR_ID))
            .leftJoin(CATEGORY_BOOK).on(BOOK.BOOK_ID.eq(CATEGORY_BOOK.BOOK_ID))
            .leftJoin(CATEGORY).on(CATEGORY_BOOK.CATEGORY_ID.eq(CATEGORY.CATEGORY_ID))
    ).where(AUTHOR.AUTHOR_ID.eq(Long.valueOf(authorId))
    ).groupBy(BOOK.BOOK_ID).orderBy(BOOK.BOOK_ID.asc())

當我執行 jOOQ 代碼時,出現以下異常:

方言默認不支持類型 class org.jooq.impl.JSONArray

我用谷歌搜索了這個異常,在這個問題中只發現了這個類似的異常。 是否有任何適當的解決方法來解決 PostgreSQL to_json function 和 array_agg() 的組合,它在給定的 aut(hor)/cat(egory) 表的所有字段上保存 DISTINCT?

更新:這是我用來以非類型安全方式在 jOOQ 中編寫查詢的另一種方式:

dslContext.resultQuery(DBQueries.GET_ALL_BOOKS_BY_AUTHOR_ID, Long.valueOf(authorId)));

...這是DBQueries.GET_ALL_BOOKS_BY_AUTHOR_ID變量的代碼:

public class DBQueries {
//...
static String GET_ALL_BOOKS_BY_AUTHOR_ID = "SELECT b.book_id AS b_id, b.title, b.price, b.amount, b.is_deleted, " +
            "to_json(array_agg(DISTINCT aut.*)) as authors, to_json(array_agg(DISTINCT cat.*)) as categories " +            
            "FROM book b " + 
            "LEFT JOIN author_book AS ab ON b.book_id = ab.book_id " +
            "LEFT JOIN author AS aut ON ab.author_id = aut.author_id " +
            "LEFT JOIN category_book AS cb ON b.book_id = cb.book_id " +
            "LEFT JOIN category AS cat ON cb.category_id = cat.category_id " +
            "WHERE aut.author_id = :id " + 
            "GROUP BY b_id ORDER BY b_id ASC;"; 
}

順便說一句,我已經更新了我的問題,以便清楚我如何使用 resultQuery() 方法來實現我想要的。 我在問如何在 jOOQ 中以盡可能類型安全的方式實現這一點,因為我有更復雜的查詢,我不知道是否可以通過不使用 PostgreSQL to_json() function 來實現。 例如,我想在 jOOQ 中創建類似的內容,例如bytefish.de web 站點的提交鏈接的“04_create_functions.sql”部分。

get_image
--------------------------------------------------------------
 {"imageid" : 1, 
  "hash" : "a3b0c44", 
  "description" : "Some Description", 
  "created_on" : "2015-03-09T22:00:45.111", 
  "comments" : [{"commentid":1, "imageid":1, "text":"Awesome!", "createdon":"2015-03-09T22:58:47.783"},
                {"commentid":2, "imageid":1, "text":"This is just a second comment.", "createdon" : "2015-03-09T22:58:47.783"}], 
  "tags" : [{"tagid":1,"name":"Cool"}, 
            {"tagid":2,"name":"Berlin"}]}
(1 row)

我正在嘗試為(書)訂單的報告做同樣的事情,其中查詢我涉及 8 個表(我沒有在此處發布該查詢,因為我試圖在 jOOQ 中解決更簡單的問題,即創建 JsonArray) .

您的具體錯誤

  • 您在 DSL.val() 中包裝了Field表達式 ( DSL.jsonArray() DSL.val() ,這意味着綁定值。 那是行不通的,並且是您的異常的原因
  • 但是,您還不能通過將普通數組包裝成JSON數組。 jOOQ 不知道您的意思是在幕后調用to_json As of jOOQ 3.13, you will have to resort to using some plain SQL templating (see example below), or alternatively, you fetch an array without turning that into JSON in your SQL logic, and turn it into JSON only in your Java client logic .

普通 SQL 模板示例:

DSL.field("to_json({0})", JSON.class, DSL.arrayAggDistinct(AUTHOR.AUTHOR_ID))

jOOQ 3.14 JSON 支持

Note that jOOQ 3.14 will support much more JSON functionality via standard SQL JSON API, and SQL Server's FOR JSON clause:

和:

正如@Lukas_Eder 指出的那樣,要解決這個問題,需要通過普通的 SQL 模板創建 JSON object,如下例所示:

DSL.field("to_json({0})", JSON.class, DSL.arrayAggDistinct(AUTHOR.AUTHOR_ID))

我在文檔中閱讀了有關上述方法的更多信息,並了解了如何根據自己的需要修改方法(為了等於在 PostgreSQL 語法中發布的問題):

DSL.field( "to_json(array_agg(DISTINCT author.*))", JSON.class, DSL.arrayAgg(AUTHOR.AUTHOR_ID) ).as("authors")

暫無
暫無

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

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