#scala #apache-spark
#scala #apache-spark
Вопрос:
Я использую Spark 2.3.1, и я извлек результирующий набор из MySQL, используя соединение JDBC. ResultSet — это тип java.sql.ResultSet. итак, как преобразовать ResultSet в объект JSON.
Мне не нужно использовать Spark SQL
Код для извлечения результирующего набора таков
var connection:Connection = null
connection: java.sql.Connection = null
scala> Class.forName(driver)
res0: Class[_] = class com.mysql.jdbc.Driver
scala> connection = DriverManager.getConnection(url, username, password)
connection: java.sql.Connection = com.mysql.jdbc.JDBC4Connection@79777da7
scala> val statement = connection.createStatement()
statement: java.sql.Statement = com.mysql.jdbc.StatementImpl@68360fb9
scala> val resultSet = statement.executeQuery("SELECT * FROM table_name")
resultSet: java.sql.ResultSet = com.mysql.jdbc.JDBC42ResultSet@4ebed2b3
Ответ №1:
вы можете получить мету результирующего набора и подсчитать количество столбцов, а затем выполнить итерацию:
val meta = resultSet.getMetaData
val colsCount = meta.getColumnCount
var colsMap: Map[Int, String] = Map.empty[Int, String]
// save col index and colName to a map, to compute later json with "key" and value
for (i <- 1 to colsCount) {
colsMap = i -> meta.getColumnName(i)
}
while (resultSet.next()) {
for (i <- 1 to colsCount) {
val value = resultSet.getObject(i)
// here you take colName from specific index and save it in a list of JsValues
// as { "colsMap(i)" : "value" }
// using spray-json or any other json library
}
}
Редактировать: Основываясь на моих исследованиях, я хочу расширить этот ответ.
Итак, чтобы преобразовать ResultSet в строку Json, я использую библиотеку JacksonMapper, для импорта этой библиотеки команда будет выглядеть следующим образом
./bin/spark-shell --packages "com.lambdaworks:jacks_2.11:2.3.3" --driver-class-path path-of/mysql-connector-java-5.1.49.jar
--jars path-of/mysql-connector-java-5.1.49.jar
-i path-to/ScalaApp.scala
Фрагмент программы
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Map
import com.lambdaworks.jacks._
val meta = query_resultSet.getMetaData
// Get total column count from metadata
val colsCount = meta.getColumnCount
var colsMap: Map[Int, String] = Map.empty[Int, String]
// Create ArrayBuffer[ArrayBuffer[Map(String, String)]]
var final_array = ArrayBuffer[ArrayBuffer[scala.collection.mutable.Map[String, String]]]()
// Fill colsMap from columnName
for (i <- 1 to colsCount) {
colsMap = i -> meta.getColumnName(i)
}
while (query_resultSet.next()) {
var result_array = ArrayBuffer[scala.collection.mutable.Map[String, String]]()
for (i <- 1 to colsCount)
{
var temp_map = scala.collection.mutable.Map[String, String]()
val cols = colsMap(i)
val value = query_resultSet.getObject(i)
temp_map(s"$cols") = s"$value"
result_array = temp_map
}
final_array = result_array
}
// for Array: use JacksMapper to convert ArrayBuffer[Map(String, String)] to [{"column1":"value1"},{"column2":"value2"}]
val json_string = JacksMapper.writeValueAsString(final_array)
Здесь мы используем библиотеку Jackson Mapper для преобразования значений карты в строку Json.
Ответ №2:
Вы можете сделать что-то вроде этого:
import value.{JsObj,JsArray}
val emp = JsObjSpec("name" -> getNameFromRS()),
"last_name" -> str(getNameFromRS()),
"profession" -> str(getProfFromRS()),
"country" -> enum("US"),
"languages" -> arrayOfStr((getLangFromRS()),
"age" -> getAgeFromRS(),,
* -> any
)
Комментарии:
1. На самом деле во время выполнения у меня нет знаний о схеме таблицы, потому что запрос будет выполняться к таблицам в соответствии с переменной цикла, поэтому не могли бы вы уточнить свой ответ, потому что я новичок в scala.
Ответ №3:
Если здесь можно использовать стороннюю библиотеку, вы можете использовать для этого функцию экспорта JSON jOOQ:
DSLContext ctx = ...
String json = ctx.fetch(resultSet).formatJSON();
Существуют различные параметры форматирования JSON для разных макетов записей и результатов. Приведенный выше пример считывается непосредственно из вашего JDBC ResultSet
, но вы могли бы, конечно, также создать и выполнить свой запрос с помощью jOOQ напрямую или использовать встроенную поддержку SQL / JSON. Часто нет необходимости писать какую-либо логику промежуточного программного обеспечения, когда вы хотите создать JSON из результатов базы данных. Вы могли бы сгенерировать JSON непосредственно из SQL.
Отказ от ответственности: я работаю в компании, стоящей за jOOQ.