我有一个用例,需要从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中使用它吗?
答案 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)
}