2015-10-16 45 views
2

我使用下面的簽名(從jOOQ)Java方法:如何用Scala的AnyVal調用Java可變參數方法?

Query query(String sql, Object... bindings); 

現在,我想打電話給裏面斯卡拉此方法AnyVal S,例如:

val id = 2 
val value = 3.14 
query(someString, id, value) 

這樣做可以使我下面的編譯器錯誤:

Error:(34, 16) overloaded method value query with alternatives: 
    (x$1: String,x$2: org.jooq.QueryPart*)org.jooq.Query <and> 
    (x$1: String,x$2: Object*)org.jooq.Query 
cannot be applied to (String, Int, Double) 
     create.query(someString, id, lat) 
      ^

不過,我可以施展每個AnyVal明確到AnyRef執行自動裝箱,從而刪除編譯器錯誤:

query(someString, id.asInstanceOf[AnyRef], value.asInstanceOf[AnyRef]) 

認識到這一點,不過,我覺得我可以寫小功能蒙上所有對象AnyRef這樣的:

def toVarargs(arg: Any, args: Any*): Array[AnyRef] = { 
    (arg +: args).map(_.asInstanceOf[AnyRef]).toArray 
} 

query(someString, toVarargs(id, value)) 

可悲的是,這並不工作以及因爲Array[AnyRef]被解釋爲一個單一的可變參數變量(其更改爲Array[Object]不作任何差異)。

人們可以通過使用_*操作,使這項工作:

query(someString, toVarargs(id, value): _*) 

然而,這似乎相當冗長。有沒有一個更優雅的解決這個問題,或者我堅持把我自己的函數與可變參數運算符結合起來?

回答

2

隨着jOOQ 3.7,沒有在Conversions type of the jOOQ-scala extensionSQLInterpolation類。它本質上只是:

implicit class SQLInterpolation(val sc : StringContext) extends AnyVal { 

    def sql(args: Any*) : SQL = 
    DSL.sql(string, args.asInstanceOf[Seq[AnyRef]] : _*) 

    def condition(args : Any*) : Condition = 
    DSL.condition(string, args.asInstanceOf[Seq[AnyRef]] : _*) 

    def table(args : Any*) : Table[Record] = 
    DSL.table(string, args.asInstanceOf[Seq[AnyRef]] : _*) 

    def query(args : Any*) : Query = 
    DSL.query(string, args.asInstanceOf[Seq[AnyRef]] : _*) 

    def resultQuery(args : Any*) : ResultQuery[Record] = 
    DSL.resultQuery(string, args.asInstanceOf[Seq[AnyRef]] : _*) 

    private def string = { 
    val pi = sc.parts.iterator 
    val sb = new StringBuilder(pi.next()) 
    var i = 0; 

    while (pi.hasNext) { 
     sb += '{' 
     sb ++= (i toString) 
     sb += '}' 
     sb ++= pi.next() 

     i = i + 1; 
    } 

    sb.result 
    } 
} 

利用這一點,你應該能夠編寫:

val id = 2 
val value = 3.14 
query"""SELECT * FROM t WHERE id = ${id} and value = ${value}""" 

上述方法的好處是,它的工作原理都與只綁定爲上述數值,或具有嵌入式SQL:

val id = 2 
val value = 3.14 
val condition = (MY_TABLE.ID === id) and (MY_TABLE.VALUE === value) 
query"""SELECT * FROM t WHERE ${condition}""" 
+0

這解決了我最初的問題。但是我發現你沒有找到比使用'args.asInstanceOf [Seq [AnyRef]]:_ *'更簡單的解決方案。 此外,什麼是你傳遞'args'到'字符串(參數)的原因'不使用他們? (也許缺少'sc.checkLengths(參數)'聲明?) – r0estir0bbe

+0

@ r0estir0bbe:是啊,'sc.checkLengths(參數)'調用被它......它到底刪除,因爲這個檢查是不是嚴格要求jOOQ的API –

+0

最後,我實際上能夠測試Scala中jOOQ的字符串插值功能。但是,我遇到了無法設置'DSLContext'的問題,因此接收到「無法執行查詢」。沒有連接配置錯誤。我做錯了什麼/有什麼方法可以事先設置'DSLContext'?我試圖讓一個'Configuration'和一個'DSLContext'隱式的,但是這對我不起作用。 – r0estir0bbe

相關問題