Spark SQL连接MySQL示例

来源:互联网 发布:淘宝主图分辨率多少 编辑:程序博客网 时间:2024/06/03 04:41

原文:https://my.oschina.net/u/1439539/blog/657973

package com.dt.spark.SparkApps.sql; 


import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 


import org.apache.spark.SparkConf; 
import org.apache.spark.api.java.JavaRDD; 
import org.apache.spark.api.java.JavaSparkContext; 
import org.apache.spark.api.java.function.VoidFunction; 
import org.apache.spark.sql.DataFrame; 
import org.apache.spark.sql.DataFrameReader; 
import org.apache.spark.sql.Row; 
import org.apache.spark.sql.SQLContext; 




/**    
@Title : SparkSQLJDBC2MySQL.java  
@Package com.dt.spark.SparkApps.sql  
* @Description: TODO(spark sql 连接mysql)  
@author 涛哥   
@date 2016年4月13日 上午9:51:45  
* @version V1.0    
*/ 
public class SparkSQLJDBC2MySQL { 


public static void main(String[] args) { 
SparkConf conf = new SparkConf().setMaster("local").setAppName("SparkSQLJDBC2MySQL"); 
JavaSparkContext sc = new JavaSparkContext(conf); 
SQLContext sqlContext = new SQLContext(sc); 
/** 
* 1,通过format("jdbc")的方式说明SparkSQL操作的数据来源是通过JDBC获得, 
* JDBC后端一般都是数据库,例如MySQL、Oracle等; 
* 2,通过DataFrameReader的option方法把要访问的数据库的信息传递进去: 
* url:代表数据库的jdbc链接地址; 
* datable:具体要链接使用哪个数据库; 
* 3,Driver部分是Spark SQL访问数据库的具体的驱动的完整报名和类名; 
*  
* 4, 关于JDBC的驱动的Jar,可以放在Spark的library目录,也可以在使用SparkSubmit的使用指定具体的Jar 
*/ 
DataFrameReader reader = sqlContext.read().format("jdbc"); 
reader.option("url","jdbc:mysql://localhost:3306/spark"); 
reader.option("dbtable", "users"); 
reader.option("driver", "com.mysql.jdbc.Driver"); 
reader.option("user", "root"); 
reader.option("password","root"); 


/** 
* 在实际的企业级开发环境中,如果数据库中数据规模特别大,例如10亿条数据,此时采用传统的DB去处理的话 
* 一般需要对10亿条数据分成很多批次处理,例如分成100批(受限于单台Server的处理能力),且实际的处理过程 
* 可能会非常复杂,通过传统的Java EE等技术可能很难或者不方便实现处理算法,此时采用Spark SQL获得数据库 
* 中的数据并进行分布式处理就可以非常好的解决该问题,但是由于Spark SQL加载DB中的数据需要时间,所以一般 
* 会在Spark SQL和具体要操作的DB之间加上一个缓冲层次,例如中间使用Redis,可以把Spark 处理速度提高到 
* 甚至45倍; *  
*/ 
DataFrame usersDataSourceDFFromMysql = reader.load(); //基于users表创建DataFrame 
usersDataSourceDFFromMysql.show(); 


List<String> peopleInformations = new ArrayList<String>(); 
peopleInformations.add("{\"name\":\"Michael\",\"age\":20,\"score\":91}"); 
peopleInformations.add("{\"name\":\"Andy\", \"age\":17,\"score\":93}"); 
peopleInformations.add("{\"name\":\"Justin\", \"age\":19,\"score\":99}"); 


JavaRDD<String> rdd = sc.parallelize(peopleInformations); 
//基于JavaRDD<String>构建DataFrame 
DataFrame personDataFrame = sqlContext.read().json(rdd); 
personDataFrame.show(); 
/** 
* 1,当DataFrame要把通过Spark SQL、Core、ML等复杂操作后的数据写入数据库的时候首先是权限的问题,必须 
* 确保数据库授权了当前操作Spark SQL的用户; 
* 2,DataFrame要写数据到DB的时候一般都不可以直接写进去,而是要转成RDD,通过RDD写数据到DB中 
*  
*/ 
personDataFrame.javaRDD().foreachPartition(new VoidFunction<Iterator<Row>>() { 
@Override 
public void call(Iterator<Row> row) throws Exception { 
Connection conn = null; 
PreparedStatement statement = null; 
Row row1 = null; 
String sql = "INSERT INTO users(NAM,AGE,SCORE) VALUES (?,?,?)"; 
try{ 
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/spark", "root", "root"); 
conn.setAutoCommit(false); 
statement = conn.prepareStatement(sql); 
int count = 0; 
while(row.hasNext()){ 
count++; 
row1 = row.next(); 
statement.setString(1, row1.getAs("name")); 
statement.setLong(2,row1.getAs("age")); 
statement.setLong(3, row1.getAs("score")); 
statement.addBatch(); 
statement.clearParameters(); 
if(count%100==0){ 
statement.executeBatch(); 


statement.executeBatch(); 
conn.commit(); 
}catch(Exception e){ 
e.printStackTrace(); 
}finally{ 
if(statement!=null){ 
statement.close(); 

if(conn!=null){ 
conn.close(); 



}); 




原创粉丝点击