【问题标题】:Passing Scala Option[List[_]] to Java JDBC Array using statement.setArray()使用 statement.setArray() 将 Scala Option[List[_]] 传递给 Java JDBC Array
【发布时间】:2023-03-04 17:18:01
【问题描述】:

我正在尝试构建从 Scala 到 JDBC callableStatements 的接口。大多数情况下,它很简单,Lists 除外。

我需要能够获取某种类型的 Scala List,并将其转换为可以传递给 statement.setArray(type, array) 的 Java 数组,但我没有任何运气(部分原因是我不知道Java 和 JDBC 非常好)。

这就是我想要做的:

for (parameter <- ps.parameters) {
    case GPArrayIn(None, t) => callableStatement.setNull(index, t)
    case GPIn(v: Some[_], Types.INTEGER) => callableStatement.setInt(index, v.get.asInstanceOf[Int])
    case GPIn(v: Some[_], Types.VARCHAR | Types.LONGVARCHAR) => callableStatement.setString(index, v.get.asInstanceOf[String])
    case GPArrayIn(v: Some[List[_]], Types.INTEGER) => callableStatement.setArray(Types.INTEGER, ???? )
    case GPArrayIn(v: Some[List[_]], Types.VARCHAR | Types.LONGVARCHAR) => callableStatement.setArray(Types.VARCHAR, ???? )
    ...

对于简单的值来说这很简单,但是当涉及到 setArray() 调用时,我就卡住了。

非常感谢任何建议。被困在这小时...

【问题讨论】:

  • 请注意,大多数驱动程序对 Array 的支持充其量是参差不齐的(如果数据库本身完全支持它们)。

标签: java arrays scala jdbc callable-statement


【解决方案1】:

setArray 采用java.sql.Array,如doc 中所述:

void setArray(int parameterIndex, Array x)
          throws SQLException

您可以创建一个:

sqlArray = connection.createArrayOf("VARCHAR", regularJavaArray);

类型:

Array createArrayOf(String typeName, Object[] elements)
                throws SQLException

如果需要,请参阅this doc 获取示例和说明。

底线:如果 Scala 集合还不是数组,则需要将其转换为 Java 数组,然后使用 createArrayOf 将该 Java 数组转换为 SQL 数组。它将数据映射到 SQL ARRAY。

至于模式匹配和提取,你可以使用类似的东西:

scala> val numbers = Array(1, 2, 3, 4)
numbers: Array[Int] = Array(1, 2, 3, 4)

scala> def arrayMatcher[T](maybeArray:  Option[Array[T]]): String =
     |     maybeArray match {
     |       case Some(a: Array[Int]) => a.mkString(",")
     |       case Some(b: Array[String]) => b.mkString("-")
     |       case None => "no array"
     |       case _ => "no match"
     |     }
arrayMatcher: [T](maybeArray: Option[Array[T]])String

scala> arrayMatcher(Some(numbers))
res0: String = 1,2,3,4

scala> arrayMatcher(None)
res1: String = no array

scala> arrayMatcher(Some(numbers map(_.toString)))
res2: String = 1-2-3-4

scala> arrayMatcher(Some(Array(1.2, 3.4)))
res3: String = no match

scala> arrayMatcher(Some(List(1, 2)))
<console>:9: error: type mismatch;
 found   : Some[List[Int]]
 required: Option[Array[?]]
              arrayMatcher(Some(List(1, 2)))
                               ^

要将列表转换为数组,请使用:

scala> List(1, 2, 3).toArray
res6: Array[Int] = Array(1, 2, 3)

【讨论】:

  • 谢谢...我知道的很多(尽管您使用 createArrayOf(string, array) 而我使用 createArray(intType, array) - 不确定这是否是一个重要的区别。问题是,我不能似乎将我的 Option[List[_]] 实例转换为 Java 数组。这是我主要坚持的部分。感谢您确认它的 Java/JDBC 端是如何工作的。
  • 哦,你的意思是模式匹配本身与提取?
  • 这让我更接近......不幸的是,只是将 Scala Array 传递给 JDBC 的 createArray() 不起作用......尝试使用 asInstanceOf[java.sql.Array] 进行强制转换,但结果为 java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.sql.Array。 .. 仍在努力。
  • Scala 数组可以用来代替 Java 数组。但是,在您的情况下,您需要 java.sql.Array,它与普通 Java 数组 [] 不同。因此,您需要将 scala/java 数组转换为 java.sql.Array,正如我在回答中所解释的那样。
  • 是的……这很重要。我们将此发布给支持人员,并回复了以下有关如何进行转换的信息:callableStatement.setArray(index, callableStatement.getConnection.createArrayOf("NUMERIC", v.get.toArray[Any].asInstanceOf[Array[AnyRef]])) 尽管我们仍在努力实施它。
猜你喜欢
  • 1970-01-01
  • 2011-04-25
  • 2015-07-18
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多