Scala Spring JdbcTemplate - 隐式转换

时间:2013-10-20 17:56:39

标签: spring scala jdbc jdbctemplate

我正在学习Scala并试图用Spring创建不同的场景。

以下代码执行完美:

def insert(student: Student): Unit = {

  jdbcTemplate.update("INSERT INTO STUDENT (ID, FIRSTNAME, LASTNAME) VALUES(?,?,?)",
        new PreparedStatementSetter() {
          def setValues(ps: PreparedStatement) {
            ps.setString(1, student.id)
            ps.setString(2, student.firstName)
            ps.setString(3, student.lastName)
          }
        })
    }
  }

但是,当我尝试隐式创建PreparedStatementSetter时,我的SQL代码失败了。

我的隐含功能是:

implicit def preparedStatementSetterImplicit(student: Student) = {
  new PreparedStatementSetter() {
    def setValues(ps: PreparedStatement) {
      ps.setString(1, student.id)
      ps.setString(2, student.firstName)
      ps.setString(3, student.lastName)
    }
  } 
}

我试图以下列方式使用它:

def insert(student: Student): Unit = {

  jdbcTemplate.update("INSERT INTO STUDENT (ID, FIRSTNAME, LASTNAME) VALUES(?,?,?)",
                            student)
}

我的SQL插入失败,出现以下异常:

Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO STUDENT (ID, FIRSTNAME, LASTNAME) VALUES(?,?,?)]; nested exception is java.sql.SQLSyntaxErrorException: incompatible data type in conversion

我的隐式转换有什么问题?

2 个答案:

答案 0 :(得分:4)

问题是编译器不需要进行隐式转换,因为jdbcTemplate.update有一个重载类型签名,只需要StringObject...,它将与{{1}匹配并且String无需隐式转换。您可以明确地执行此操作(我认为在代码中可读性更好),如下所示:

Student

答案 1 :(得分:1)

您是否尝试过明确键入转换,例如:

implicit def student2pss(student: Student) : PreparedStatementSetter = {...}

隐式转化仅在转化后的类型与完全预期的类型匹配时使用(并且没有明确输入您的转换会返回匿名类型,而不是PreparedStatementSetter),所以我不确定转换是否正在进行一点也没用过。尝试将println添加到转化中,看看它是否会被解雇。

修改 要解决此问题,您可能需要为JdbcTemplate创建自己的包装并提供转换:

class JdbcTemplateWrapper(val template: JdbcTemplate) {
    def wrappedUpdate[DataType](statement: String, data: DataType)(implicit conv: DataType => PreparedStatementSetter) = {
        template.update(statement, conv(data))
    }
}
object JdbcTemplateWrapper {
    implicit def wrapJdbc(template: JdbcTemplate) = new JdbcTemplateWrapper(template)
}

在范围内有一行

jdbcTemplate.customUpdate("INSERT INTO STUDENT (ID, FIRSTNAME, LASTNAME) VALUES(?,?,?)",
                        student)

首先将jdbcTemplate隐式转换为JdbcTemplateWrapper(以使其回复cusomUpdate,然后将Student隐式转换为PreparedStatementSetter