写入mysql_spark写入mysql优化

3d0b919e727b7d5ff97a4ee86c50b1b8.png

前言

在某一些时候,我们需要将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()
				}
			}

		})


	}
}

我们再看这段代码,发现其中只需要每一个分区进行一次数据库链接就行了,一下子减少了数据库的链接,在正式的环境中,建议使用第二种方式。

总结

点击关注不迷路哦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值