spark操作数据库的几种方法
一.使用jdbcRDD的接口:
SparkConf conf = new SparkConf();
conf.setAppName("Simple Application").setMaster("local");
JavaSparkContext jsc = new JavaSparkContext(conf); //1.直接使用jdbcRDD的构造函数
class DbConnection extends AbstractFunction0<Connection> implements
Serializable {
private static final long serialVersionUID = 1L;
private String driverClassName;
private String connectionUrl;
private String userName;
private String password; public DbConnection(String driverClassName, String connectionUrl,
String userName, String password) {
this.driverClassName = driverClassName;
this.connectionUrl = connectionUrl;
this.userName = userName;
this.password = password;
} @Override
public Connection apply() {
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
}
Properties properties = new Properties();
properties.setProperty("user", userName);
properties.setProperty("password", password);
Connection connection = null;
try {
connection = DriverManager.getConnection(connectionUrl,
properties);
} catch (SQLException e) {
}
return connection;
}
} class MapResult extends AbstractFunction1<ResultSet, Object[]>
implements Serializable {
private static final long serialVersionUID = 1L; public Object[] apply(ResultSet row) {
return JdbcRDD.resultSetToObjectArray(row);
}
} String Connection_url = "jdbc:mysql://ip:port/dbname?useUnicode=true&characterEncoding=utf8";
String Driver="com.mysql.jdbc.Driver";
String UserName = "root";
String password = "pd";
DbConnection dbConnection = new DbConnection(Driver,
Connection_url, UserName, password);
sql = "select * from (" + sql + ") as tmp where 0=? and 0=?";
//lowerBound,upperBound均设置0,where条件就为恒真,这个是个处理技巧
JdbcRDD<Object[]> jdbcRDD = new JdbcRDD<>(jsc.sc(), dbConnection,
sql, , , , new MapResult(),
ClassManifestFactory$.MODULE$.fromClass(Object[].class));
JavaRDD<Object[]> javaRDD = JavaRDD.fromRDD(jdbcRDD,
ClassManifestFactory$.MODULE$.fromClass(Object[].class)); //另外一种实现:
class DbConnectionFactory implements JdbcRDD.ConnectionFactory {
private static final long serialVersionUID = 1L;
private String driverClassName;
private String connectionUrl;
private String userName;
private String password; public Connection getConnection() throws Exception {
Class.forName(driverClassName);
String url = connectionUrl;
Properties properties = new Properties();
properties.setProperty("user", userName);
properties.setProperty("password", password);
return DriverManager.getConnection(url, properties);
} public DbConnectionFactory(String driverClassName, String connectionUrl,
String userName, String password) {
this.driverClassName = driverClassName;
this.connectionUrl = connectionUrl;
this.userName = userName;
this.password = password;
} } String Connection_url = "jdbc:mysql://ip:port/dbname?useUnicode=true&characterEncoding=utf8";
sql = "select * from (" + sql + ") as tmp where 0=? and 0=?";
DbConnectionFactory ConnectFactory = new DbConnectionFactory(Driver,
Connection_url, UserName, password)
javaRDD = JdbcRDD.create(jsc, new DbConnectionFactory(Driver,
Connection_url, UserName, password), sql, , , ,new Function<ResultSet,Object[]>()
{
private static final long serialVersionUID = 1L;
public Object[] call(ResultSet resultSet)
{
return JdbcRDD.resultSetToObjectArray(resultSet);
}
});//直接返回JavaRDD<Object[]>,这个底层调用的是JdbcRDD(SparkContext sc, Function0<Connection> getConnection, String sql, long lowerBound, long upperBound, int numPartitions, Function1<ResultSet, T> mapRow, ClassTag<T> evidence$1)
//javaRDD =JdbcRDD.create(jsc, ConnectFactory, sql, 0, 0, 1);//该方法更加简洁,底层调用上面的create(JavaSparkContext paramJavaSparkContext, ConnectionFactory paramConnectionFactory, String paramString, long paramLong1, long paramLong2, int paramInt, Function<ResultSet, T> paramFunction)
二.使用通过sparksession的接口:
SparkSession ss = SparkSession.builder().config(conf).enableHiveSupport().getOrCreate()
//读取方式1
String sql = "(select * from xxx) as tmp; //注意这里的sql格式,该sql也可以直接是一个表名
Dataset<Row> df = session.read().format("jdbc")
.option("url", jdbcURL)
.option("driver", driver)
.option("dbtable", sql)
.option("user", username)
.option("password", password)
.load();
//读取方式2:
Properties connectionProperties = new Properties();
connectionProperties.put("user", username);
connectionProperties.put("password", password);
connectionProperties.put("driver", driver);
session.read().jdbc(url, table, properties)
df = session.read().jdbc(jdbcURL,sql,connectionProperties); //写入方式1:
String saveMode = "Overwrite";
df.write().mode(saveMode).jdbc(jdbcURL, tablename, connectionProperties);
//写入方式2:
final String sql = "insert into tab_xxx (c1,c2,c3) values(?,?,?)"; df.javaRDD().foreachPartition(new VoidFunction<Iterator<Row>>() {
private static final long serialVersionUID = -834520661839866305L;
@Override
public void call(Iterator<Row> t) throws Exception {
Class.forName(driver);
Connection conn = (Connection) DriverManager.getConnection(url, username, password);
conn.setAutoCommit(false);
try {
PreparedStatement pstmt = (PreparedStatement) conn.prepareStatement(sql);
int loop = ;
while (t.hasNext()) {
Row row = t.next();
for (int i = ; i < ; i++) { //这里的3是插入的列只有3列
pstmt.setObject(i + , row.get(i));
}
pstmt.executeUpdate();
if (++loop % == ) {
conn.commit();
}
}
conn.commit();
pstmt.close();
} finally {
conn.close();
}
}
});
}
//写入方法3
3.转换成List<Row>,可以批量写入,但是有可能导致Driver 内存承载过高 private static void InsertTmpTable(Connection conn,Dataset<Row> ndf,final String m_cols,final String tabname) {
System.out.println("InsertTmpTab "+tabname+" start!");
String placeholderStr="values(";
int cnt = m_cols.split(",").length+1;
for(int i = 0;i<cnt;i++){
placeholderStr+="?"+ (i == cnt-1 ? ")" : ",");
} String sql = "insert into "+ tabname+"("+m_cols+",orderby_time)"+placeholderStr;
PreparedStatement pstmt = null; try {
List<Row> lrow=ndf.collectAsList();
pstmt = (PreparedStatement) conn.prepareStatement(sql); for(int j =0;j<lrow.size();j++){
for(int i=0;i<cnt;i++){
pstmt.setObject(i+1,lrow.get(j).get(i));
}
pstmt.executeUpdate();
if(j%10000==0) //批量提交
conn.commit();
}
conn.commit();
pstmt.close();
}catch (Exception e){
System.out.println(e.getMessage());
System.exit(-1);
}
System.out.println("InsertTmpTab "+tabname+" success!");
}
spark操作数据库的几种方法的更多相关文章
- Yii操作数据库的3种方法
一.执行原生太SQL的PDO方式. 复制代码代码如下: $sql = "";//原生态sql语句 xx::model()->dbConnection->createCo ...
- 将Excel数据导入mysql数据库的几种方法
将Excel数据导入mysql数据库的几种方法 “我的面试感悟”有奖征文大赛结果揭晓! 前几天需要将Excel表格中的数据导入到mysql数据库中,在网上查了半天,研究了半天,总结出以下几种方法,下面 ...
- python更新数据库脚本两种方法
最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新 import MySQ ...
- Shell脚本中执行sql语句操作mysql的5种方法【转】
对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的 ...
- C++连接mysql数据库的两种方法
本文主要介绍了C++连接mysql数据库的两种方法,希望通过本文,能对你有所帮助,一起来看. 现在正做一个接口,通过不同的连接字符串操作不同的数据库.要用到mysql数据库,以前没用过这个数据库,用a ...
- python更新数据库脚本三种方法
最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新 import MySQ ...
- Yii框架操作数据库的几种方式与mysql_escape_string
一.Yii操作数据库的几种选择 1,PDO方式. $sql = "";//原生态sql语句 xx::model()->dbConnection->createComma ...
- 【Python】python更新数据库脚本两种方法
最近项目的两次版本迭代中,根据业务需求的变化,需要对数据库进行更新,两次分别使用了不同的方式进行更新. 第一种:使用python的MySQLdb模块利用原生的sql语句进行更新 1 import ...
- Linux 下操作GPIO(两种方法,驱动和mmap)(转载)
目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...
随机推荐
- UIScrollView的常用属性
UIScrollView的常用属性
- 使用 JavaScript 实现名为 flatten(input) 的函数,可以将传入的 input 对象(Object 或者 Array)进行扁平化处理并返回结果
请使用 JavaScript 实现名为 flatten(input) 的函数,可以将传入的 input 对象(Object 或者 Array)进行扁平化处理并返回结果.具体效果如下: const in ...
- unittest单元测试框架之unittest案例(二)
1.待测方法: # 加法,返回 a+b 的值 def add(a,b): return a+b # 减法,返回 a-b 的值 def minus(a,b): return a-b # 乘法,返回 a* ...
- javascript根据文件字节数返回文件大小
function getFileSize(fileByte) { var fileSizeByte = fileByte; var fileSizeMsg = ""; if(fil ...
- Linux每日一命令:【00】总纲
Linux每日一命令更新频率为每周5篇. 文章结构如下: 简介 语法 选项 参数 常用实例 实用技巧(可选) 参考文档 文章目录如下: 2018-02-19 20:15 -- Linux每日一命令:[ ...
- 「PHP」观察者模式模式
引言 所属:行为型模式,常用设计模式之一 学习资料: <大话设计模式>程杰 模式概述 观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象.这个主题 ...
- Hbase 表的Rowkey设计避免数据热点
一.案例分析 常见避免数据热点问题的处理方式有:加盐.哈希.反转等方法结合预分区使用. 由于目前原数据第一字段为时间戳形式,第二字段为电话号码,直接存储容易引起热点问题,通过加随机列.组合时间戳.字段 ...
- python中字符串的常见操作
demo:mystr = 'hello python' 1.find:mystr.find(str, start=0, end=len(mystr)),检测字符串中是否有要查询的字符,如果有返回开始的 ...
- Python 爬虫 (一)
爬: 爬一个网站需要几步? 确定用户的需求 根据需求,寻找网址 读取网页 urllib request requests 定位并提取数据 正则 xpath beautiful soup 存储数据 my ...
- linux 通过 openconnect 来连接学校内网
参考 http://xingda1989.iteye.com/blog/1969908 https://blog.csdn.net/edin_blackpoint/article/details/70 ...