【问题标题】:BigQuery TableResult casting optionsBigQuery TableResult 转换选项
【发布时间】:2021-08-05 15:36:02
【问题描述】:

如何将 TableResult 转换为以下格式 List<Map<String, Any>>

Map 分别包含列和它的值。多行被添加到列表中。

我尝试了类似的方法,但它会引发错误 -> com.google.cloud.bigquery.TableResult cannot be cast to java.util.List

            val queryConfig = QueryJobConfiguration.newBuilder(
                modSql
            )
                .setUseLegacySql(false).build()
            val queryJob = bigQuery.create(JobInfo.newBuilder(queryConfig).build())
            val result = queryJob.getQueryResults()
            return result as List<Map<String, Any>>;

我们如何复制类似于 jdbc 模板的东西。例如使用 jdbc 模板,我们可以这样做

jdbc.query(sql, rowMapper)

这会以特定的 rowMapper 格式返回结果。我们如何使用 BigQuery 实现这一目标?

【问题讨论】:

    标签: java kotlin jdbc google-bigquery jdbctemplate


    【解决方案1】:

    如果你想拥有类似Spring的API,你需要:

    1. 声明相同的接口:
    fun interface RowMapper<T> {
        fun mapRow(row: FieldValueList, rowNum: Int): T
    }
    
    1. 想出一些方法将RowMapper 包含到查询结果转换管道中。例如,通过TableResult 类的扩展方法:
    fun <T> TableResult.mapWith(rowMapper: RowMapper<T>): Iterable<T> = Iterable {
        iterator {
            yieldAll(iterateAll().withIndex().map { (index, row) -> rowMapper.mapRow(row, index) })
        }
    }
    

    RowMapper 实现返回映射到其值的列名:

    class RowMapperToMap(schema: Schema) : RowMapper<Map<String, Any>> {
        private val fieldsNames = schema.fields.map { it.name }
    
        override fun mapRow(row: FieldValueList, rowNum: Int) = fieldsNames.associateWith { row.get(it).value }
    }
    

    用法:

    val result = queryJob.getQueryResults()
    return result.mapWith(RowMapperToMap(result.schema))
    

    【讨论】:

    • 感谢您的简短解释。这就像一个魅力!欣赏它。
    • 同时,我们可以在这个逻辑中将列名修改为小写吗?
    • 是的,只需在RowMapper 实现中再添加一个转换:fieldsNames.associateWith { row.get(it) }.mapKeys { it.key.lowercase() }
    • 解决方案的问题是,最后所有值都以字符串形式生成,而不是表上声明的内容
    • 实际上,row.get(it) 返回一个FieldValue。它是任意类型的基础值的包装类。要以最通用的形式 (Object) 获得它,它需要再进行一次转换:row.get(it).value。更新了我的答案。
    猜你喜欢
    • 2023-02-09
    • 1970-01-01
    • 2018-07-30
    • 2020-08-04
    • 1970-01-01
    • 2018-10-05
    • 2016-11-14
    • 2020-08-31
    • 2021-06-07
    相关资源
    最近更新 更多