2015-10-16 82 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

相关问题