![3d0b919e727b7d5ff97a4ee86c50b1b8.png](https://i-blog.csdnimg.cn/blog_migrate/ec2367883cad91ad2da8d26daeef3dc3.jpeg)
前言
在某一些时候,我们需要将spark处理的结果写入到数据库中,下面我将展示两种方式。
foreach
package com.cn.spark.write
import java.sql.DriverManager
import org.apache.spark.{SparkConf, SparkContext}
/**
* 实现写入mysql表中,用foreach
*/
object writeMysql {
def main(args: Array[String]): Unit = {
//构建sparkConf
val conf = new SparkConf().setAppName("test").setMaster("local[2]")
//构建sparkContext
val sc = new SparkContext(conf)
//读取文件
val data = sc.textFile("/Users/mac/IdeaProjects/spark/src/resources/user.txt")
//切换每一行
var result = data.map(x => x.split(",")).map( x => (x(0),x(1),x(2).toInt))
//把数据保存到mysql中
result.foreach( line => {
//建立mysql链接
val connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/menagerie","root","123")
//定义插入数据的sql语句
val sql = "insert into user(id,name,age) values(?,?,?)"
//获取PreParedStatement
try{
val ps = connection.prepareStatement(sql)
ps.setString(1,line._1)
ps.setString(2,line._2)
ps.setInt(3,line._3)
ps.execute()
}catch {
case e:Exception => e.printStackTrace()
}finally {
if(connection != null){
connection.close()
}
}
})
}
}
可以通过观察,我们用的foreach,然后有多少条数据就会创建多少条数据库链接,那么有什么版本可以减少数据库的链接吗?且看下面的方法。
foreachPartition
package com.cn.spark.write
import java.sql.{Driver, DriverManager}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* 用partition来进行mysql链接
*/
object writeMysqlPartition {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("test").setMaster("local[2]")
var sc = new SparkContext(conf)
val data = sc.textFile("/Users/mac/IdeaProjects/spark/src/resources/user.txt")
var result = data.map(x => x.split(",")).map(x => (x(0).toInt, x(1).toString , x(2).toInt))
result.foreachPartition(line => {
//进行数据库链接
val connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/menagerie","root","123")
try{
//构建sql语句
val sql = "insert into user(id,name,age) values(?,?,?)"
//预备语句
val ps = connection.prepareStatement(sql)
//给每一个字段添加值
line.foreach(x=>{
ps.setInt(1,x._1)
ps.setString(2,x._2)
ps.setInt(3,x._3)
//开始执行
ps.execute()
})
}catch {
case e:Exception => e.printStackTrace()
}finally {
if(connection != null){
connection.close()
}
}
})
}
}
我们再看这段代码,发现其中只需要每一个分区进行一次数据库链接就行了,一下子减少了数据库的链接,在正式的环境中,建议使用第二种方式。
总结
点击关注不迷路哦!