簡體   English   中英

有沒有比一直調用 `val` 更好的方法來調用生成表的 function?

[英]Is there a better way to invoke a table-producing function other than calling `val` all the times?

我從數據庫調用 function,為簡單起見,命名為some_table_generating_function ,以便將查詢轉換為返回Field<Array<UUID>>的 select 語句,它迫使我使用 DSL 的val function,並且它為執行簡單的 function 調用創建了很多樣板。

以下示例有效,但似乎過度使用了val function,您對清理這段代碼有什么建議嗎?

context
  .select()
  .from(
    select(
      // fields to be selected
    )
      .from(
        Public.SOME_TABLE_GENERATING_FUNCTION(
          `val`(someString.capitalise()),
          `val`(someInt),
          `val`(BigDecimal(someDecimalString)),
          `val`(someInt),
          `val`(BigDecimal(anotherDecimalString)),
          `val`(BigDecimal(yetAnotherDecimalString)),
          `val`(anotherInt),
          `val`(someLong),
          `val`(anotherLong),
          // the important bit: uuid[] parameter expected for this parameter
          field(
            "ARRAY({0})::uuid[]",
            select(A_TABLE.UUID.cast(String::class.java))
              .from(A_TABLE)
              .innerJoin(ANOTHER_TABLE)
              .on(A_TABLE.UUID.eq(ANOTHER_TABLE.UUID))
              .where(
                // additional conditions
              )
          ) as Field<Array<UUID>>
        )
      )
      .join(THE_TABLE)
      .asTable("inner_query")
  )
  .where(
    // additional conditions
  )

便利重載可用性的背景

jOOQ 的 API 不能為更大數量的n重載TnField<Tn>的所有可能組合,其中n是 function 參數的數量。 例如:

  • 1 個參數 = 2 個重載( f(T1)f(F<T1>)
  • 2 個參數 = 4 個重載( f(T1, T2) , f(T1, F<T2>) , f(F<T1>, T2) , f(F<T1>, F<T2>)
  • 3 個參數 = 8 個重載
  • n 個參數 = 2^n 個重載

雖然 DSL API 通常為 2 個參數提供完整的重載,但它在 3 個參數時停止,總共只提供 2 個重載:

  • 接受綁定值的重載
  • 接受表達式的重載

這與生成的用戶定義函數的便利重載相同。

更詳細的調用語法的可能性

普通例程同時支持便捷語法和更冗長的調用語法:

// Convenience call
Routines.ordinaryRoutine(1, 2)

// Verbose way to call the routine, equivalent to the above
val r = OrdinaryRoutine()
r.param1 = 1
r.param2 = 2

這目前不適用於表值函數,它只知道“方便語法”。 可能值得研究生成調用表值函數的替代方法:

解決方法

  • 您可以創建一個輔助 function 調用您的 function 但接受 UDT ( CREATE TYPE ) 形式的第一組參數,因此您只需將單個 UDT 參數包裝在DSL.val()中一次。 就 function API 設計而言,這並不能很好地擴展,但它可以解決這個問題
  • 您可以為 function 調用使用普通 SQL 模板( from("f(?, ?, ... {0})", someString.capitalise(), someInt, ..., field(...)) ),因為您已經在使用普通的 SQL 模板。 不過,這不是類型安全的。
  • 您可以擴展JavaGenerator以針對您的特定情況生成額外的重載

就個人而言,我認為這些解決方法中的任何一個都不是很實用。 由於您可能不會經常遇到這種情況,因此我會堅持使用顯式val調用的原始調用

暫無
暫無

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

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