Spark如何与JDBC连接一起使用?

时间:2018-07-23 19:09:15

标签: apache-spark

我是Spark的新手,我正在尝试开发一个spark-jdbc程序来计算数据库中的行数。

我想出了以下代码:

object PartitionRetrieval {
    var conf  = new SparkConf().setAppName("Spark-JDBC")
    val log   = LogManager.getLogger("Spark-JDBC Program")
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conFile       = "/home/hmusr/ReconTest/inputdir/testconnection.properties"
    val properties    = new Properties()
    properties.load(new FileInputStream(conFile))
    val connectionUrl = properties.getProperty("gpDevUrl")
    val devUserName   = properties.getProperty("devUserName")
    val devPassword   = properties.getProperty("devPassword")
    val driverClass   = properties.getProperty("gpDriverClass")
    val tableName     = "source.bank_accounts"
    try {
    Class.forName(driverClass).newInstance()
    } catch {
    case cnf: ClassNotFoundException =>
        log.error("Driver class: " + driverClass + " not found")
        System.exit(1)
    case e: Exception =>
        log.error("Exception: " + e.printStackTrace())
        System.exit(1)
    }
    def main(args: Array[String]): Unit = {
        val spark   = SparkSession.builder().config(conf).master("yarn").enableHiveSupport().getOrCreate()
        val gpTable = spark.read.format("jdbc").option("url", connectionUrl)
                                                        .option("dbtable",tableName)
                                                        .option("user",devUserName)
                                                        .option("password",devPassword).load()
        val rc = gpTable.filter(gpTable("source_system_name")==="ORACLE").count()
        println("gpTable Count: " + rc)
    }
}

到目前为止,此代码正在运行。但是我对此有两个概念上的疑问。

  1. 在Java中,我们创建一个连接类,并使用该连接查询多个表,并在满足我们的要求后将其关闭。但这似乎以不同的方式起作用。 如果我必须查询数据库中的10个表,则应在其中使用不同的表名使用此行10次: 在Java中,我们创建一个连接类,并使用该连接查询多个表,并在满足我们的要求后将其关闭。但这似乎以不同的方式起作用。 如果我必须查询数据库中的10个表,我应该在其中使用不同的表名使用此行10次:

    val gpTable = spark.read.format("jdbc").option("url", connectionUrl)
                                                    .option("dbtable",tableName)
                                                    .option("user",devUserName)
                                                    .option("password",devPassword).load()
    
  2. 此处使用的当前表的总行数为2000。我可以相应地使用filter / select / aggregate函数。 但是在我们的产品中,有几百万行的表,如果我在上面的语句中放入一个巨大的表,即使我们的要求后来又过滤了它,难道不是先创建一个巨大的数据帧吗?

有人能对我上面提到的疑问给予一些见解吗?

1 个答案:

答案 0 :(得分:1)

向其传递一个SQL查询,该查询首先称为下推数据库。

例如

val dataframe_mysql = spark.read.jdbc(jdbcUrl, "(select k, v from sample where k = 1) e", connectionProperties)  

您可以用s“”“ k = 1代替hostvars,或者按照您的建议构建自己的SQL字符串并重用,但是如果不这样做,世界仍然存在。