地图中的Spark Scala中的单例

时间:2018-10-16 01:32:39

标签: scala apache-spark

我有一个用例,需要从spark写入postgres数据库,

我已经将传入的文件读到rdd,我的最终结果是可以写入postgres的rdd。在rdd map函数中,我试图创建jdbc模板并写入postgres。我希望我的jdbc模板为Singleton和我已经将jdbctemplate设置为Object。但是,它似乎仍然无法正常工作,并且打开了太多的连接。

rddToPostgres.map(postgresdata => toPostgresDatabase(r))




toPostgresDatabase(postgresdata:Row) {

var dataToLoad = new MapSqlParameterSource().addValue("Nifi_Param",postgresdata.getAs("Nifi_Param")

var insertStatement = "insert in to postgresschema.nifitab(nifi_param) values(:nifi_param)"

new JdbcTemplate().getJdbcConn().update(insertStatement,dataToLoad)

}

}

Object JdbcTemplate(){


def getJdbcConn() {

new NamedParameterJdbcTemplate(new DriverManagerDataSource().setDriverClassName().setPassword("XXXXX").setUsername("XXXXX"));
}

尽管JdbcTemplate是单例的,因为它被定义为对象,因此多次调用它,有人可以建议如何在scala中创建单例并在rdd.map中使用它吗?

1 个答案:

答案 0 :(得分:0)

由于getJdbcConn是一个函数(def),因此每次调用时都会对其求值。如果您将其设置为val,它将只被评估一次。

此外,无需通过new实例化对象。

object JdbcTemplate {
  val jdbcConnection = new NamedParameterJdbcTemplate(new DriverManagerDataSource().setDriverClassName().setPassword("....").setUsername("....")
}

rddToPostgres.map { postgresData: Row =>
  val dataToLoad = new MapSqlParameterSource().addValue("Nifi_Param", postgresData.getAs("Nifi_Param"))
  val insertStatement = "insert in to postgresschema.nifitab(nifi_param) values(:nifi_param)"

  JdbcTemplate.jdbcConnection.update(insertStatement, dataToLoad)
}