当前位置: 首页 > news >正文

Spark【Spark SQL(二)RDD转换DataFrame、Spark SQL读写数据库 】

从 RDD 转换得到 DataFrame

Saprk 提供了两种方法来实现从 RDD 转换得到 DataFrame:

  1. 利用反射机制推断 RDD 模式
  2. 使用编程方式定义 RDD 模式

下面使用到的数据 people.txt :

Tom, 21
Mike, 25
Andy, 18

1、利用反射机制推断 RDD 模式

        在利用反射机制推断 RDD 模式的过程时,需要先定义一个 case 类,因为只有 case 类才能被 Spark 隐式地转换为DataFrame对象。

object Tese{// 反射机制推断必须使用 case 类,case class 必须放到main方法之外case class Person(name: String,age: Long)  //定义一个case类def main(args: Array[String]): Unit = {val spark = SparkSession.builder().master("local[*]").appName("rdd to df 1").getOrCreate()import spark.implicits._ //这里的spark不是org.apache.spark这个包 而是我们创建的SparkSession对象 它支持把一个RDD隐式地转换为一个 DataFrame对象val rdd: RDD[Person] = spark.sparkContext.textFile("data/sql/people.txt").map(line => line.split(",")).map(t => Person(t(0), t(1).trim.toInt))// 将RDD对象转为DataFrame对象val df: DataFrame = rdd.toDF()df.createOrReplaceTempView("people")spark.sql("SELECT * FROM people WHERE age > 20").show()spark.stop()}
}

注意事项1:

case 类必须放到伴生对象下,main方法之外,因为在隐式转换的时候它会自动通过 伴生对象名.case类名 来调用case类,如果放到main下面就找不到了。

注意事项2:

import spark.implicits._
这里的spark不是org.apache.spark这个包 而是我们上面创建的SparkSession对象 它支持把一个RDD隐式地转换为一个 DataFrame对象

2、使用编程方式定义 RDD 模式

        反射机制推断时需要定义 case class,但当无法定义 case 类时,就需要采用编程式来定义 RDD 模式了。这种方法看起来比较繁琐,但是很好用,不容易报错。

        我们现在同样加载 people.txt 中的数据,生成 RDD 对象,再把RDD对象转为DataFrame对象,进行SparkSQL 查询。主要包括三个步骤:

  1. 制作表头 schema: StructType
  2. 制作表中记录 rowRDD: RDD[Row]
  3. 合并表头和记录 df:DataFramw
def main(args: Array[String]): Unit = {val spark = SparkSession.builder().master("local[*]").appName("rdd to df 2").getOrCreate()//1.制作表头-也就是定义表的模式val schema: StructType = StructType(Array(StructField("name", StringType, true),StructField("age", IntegerType, true)))//2.加载表中的记录-也就是读取文件生成RDDval rowRdd: RDD[Row] = spark.sparkContext.textFile("data/sql/people.txt").map(_.split(",")).map(attr => Row(attr(0), attr(1).trim.toInt))//3.把表头和记录拼接在一起val peopleDF: DataFrame = spark.createDataFrame(rowRdd, schema)peopleDF.createOrReplaceTempView("people")spark.sql("SELECT * FROM people WHERE age > 20").show()spark.stop()}

运行结果:

+----+---+
|name|age|
+----+---+
| Tom| 21|
|Mike| 25|
+----+---+

Spark SQL读取数据库

导入依赖

根据自己本地的MySQL版本导入对应的驱动。

注意:mysql8.0版本在JDBC中的url是:" com.mysql.cj.jdbc.Driver "

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency>

读取 MySQL 中的数据

def main(args: Array[String]): Unit = {val spark = SparkSession.builder().master("local[*]").appName("jdbc spark sql").getOrCreate()val mysql: DataFrame = spark.read.format("jdbc").option("url", "jdbc:mysql://localhost:3306/spark").option("driver", "com.mysql.cj.jdbc.Driver").option("dbtable", "student").option("user", "root").option("password", "Yan1029.").load()mysql.show()spark.stop()}

运行结果:

默认显示整张表

+---+----+---+---+
| id|name|age|sex|
+---+----+---+---+
|  1| Tom| 21| 男|
|  2|Andy| 20| 女|
+---+----+---+---+

向 MySQL 写入数据

def main(args: Array[String]): Unit = {val spark = SparkSession.builder().master("local[*]").appName("jdbc spark sql").getOrCreate()//导入两条student信息val rdd: RDD[Array[String]] = spark.sparkContext.parallelize(Array("3 Mike 22 男", "4 Cindy 23 女")).map(_.split(" "))//设置模式信息-创建表头val schema: StructType = StructType(Array(StructField("id", IntegerType, true),StructField("name", StringType, true),StructField("age", IntegerType, true),StructField("sex", StringType, true)))//创建Row对象 每个 Row对象都是表中的一行-创建记录val rowRDD = rdd.map(stu => Row(stu(0).toInt, stu(1), stu(2).toInt, stu(3)))//创建DataFrame对象 拼接表头和记录val df = spark.createDataFrame(rowRDD, schema)//创建一个 prop 变量 用来保存 JDBC 连接参数val prop = new Properties()prop.put("user","root")prop.put("password","Yan1029.")prop.put("driver","com.mysql.cj.jdbc.Driver")//写入数据 采用 append 模式追加df.write.mode("append").jdbc("jdbc:mysql://localhost:3306/spark","spark.student",prop)spark.stop()}

运行结果:


总结

        今天上午就学到这里,本想着今天专门看看StructType、StructField和Row这三个类的,没想到就在这节课。这一篇主要学了RDD对象向DataFrame对象的转换以及Spark SQL如何读取数据库、写入数据库。

        下午学完这一章最后的DataSet。

相关文章:

Spark【Spark SQL(二)RDD转换DataFrame、Spark SQL读写数据库 】

从 RDD 转换得到 DataFrame Saprk 提供了两种方法来实现从 RDD 转换得到 DataFrame&#xff1a; 利用反射机制推断 RDD 模式使用编程方式定义 RDD 模式 下面使用到的数据 people.txt &#xff1a; Tom, 21 Mike, 25 Andy, 18 1、利用反射机制推断 RDD 模式 在利用反射机制…...

LabVIEW检测润滑油中的水分和铁颗粒

LabVIEW检测润滑油中的水分和铁颗粒 润滑油广泛应用于现代机械设备&#xff0c;由于工作环境日益恶劣&#xff0c;润滑油经常被水分乳化&#xff0c;加速对机械设备的腐蚀。此外&#xff0c;润滑油还受到机械零件摩擦中产生的Fe颗粒的污染&#xff0c;削弱了其机械润滑效果。润…...

【新版】系统架构设计师 - 软件架构设计<SOA与微服务>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 架构 - 软件架构设计&#xff1c;SOA与微服务&#xff1e; 考点摘要 面向服务SOA&#xff08;★★★★&#xff09;微服务&#xff08;★★★★&#xff09; 基于/面向服务的&#xff08;SOA&#xff09; 在SO…...

React+Typescript+react-router 6 创建路由操作

本文我们来看看路由的安装 其实路由的操作没有什么变化 但是还是给大家讲一下 那么我们打开项目 在项目终端输入 npm install --save react-router react-router-dom安装 一下 react-router 和 react-router-dom 这都是react开发很基本的插件了 不过大家安装前先注意好我的版…...

前端list.push,封装多个对象

js var fruit [apple, banana];fruit.push(pear);console.log(fruit); // [apple, banana, pear]现在为对象 data1:{addUser: 1,editUser: 1,addTime: null,editTime: 1527410579000,userId: 3,systemNo: mc,userName: zengzhuo,userPassword: e10adc3949ba59abbe56e057f20f88…...

指令延迟隐藏

一、指令延迟隐藏 1. 延迟和延迟隐藏 指令延迟指计算指令从调度到指令完成所需的时钟周期如果在每个时钟周期都有就绪的线程束可以被执行&#xff0c;此时GPU处于满符合状态指令延迟被GPU满负荷计算状态所掩盖的现象称为延迟隐藏延迟隐藏对GPU编程开发很重要&#xff0c;GPU设…...

《React vs. Vue vs. Angular:2023年的全面比较》

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

win10自带wifi共享功能

1、按下【wini】组合键打开windows设置&#xff0c;点击【网络和internet】&#xff1b; 2、按照下图&#xff0c;打开个移动热点&#xff0c;设置名称、密码。...

React如何实现国际化?

目录 一、Redux准备工作 commonTypes.js commonActions.js commonReducer.js rootReducer.js 二、然后定义SelectLang组件 index.js index.less 三、创建语言包 welcomeLocale.js index.js 四、使用 react的入口文件 App.js welcome.js 附 关于如何实现国际…...

netrw模拟nerdtree的go命令连续打开多个文件

vim9自带的文件浏览器netrw功能很强大。过去用惯了nerdtree的我&#xff0c;对netrw的文件操作还要适应一些时间。 使用netrw一段时间后发现它没有nerdtree的go命令的替代操作&#xff0c;今天就自制一个。 一、制作go命令&#xff1a; nerdtree的go命令功能&#xff1a;就是…...

算法通关村第十九关——动态规划高频问题(白银)

算法通关村第十九关——动态规划高频问题&#xff08;白银&#xff09; 前言1 最少硬币数2 最长连续递增子序列3 最长递增子序列4 完全平方数5 跳跃游戏6 解码方法7 不同路径 II 前言 摘自&#xff1a;代码随想录 动态规划五部曲&#xff1a; 确定dp数组&#xff08;dp tabl…...

Matlab如何导入Excel数据并进行FFT变换

如果你发现某段信号里面有干扰&#xff0c;想要分析这段信号里面的频率成分&#xff0c;就可以使用matlab导入Excel数据后进行快速傅里叶变换&#xff08;fft&#xff09;。 先直接上使用方法&#xff0c;后面再补充理论知识。 可以通过串口将需要分析的数据发送到串口助手&a…...

华为mate60 上线 媒介盒子多家媒体报道

为什么你的品牌营销不见效&#xff1f;如何能推动品牌破圈&#xff1f;让媒介盒子给你一些启发。本期盒子要跟大家分享地新机上市&#xff0c;数码科技行业企业该如何做线上宣传。 HUAWEI Mate 60系列8月29日官宣发布&#xff0c;出色的拍照功能、强大的性能表现和持久的续航能…...

Java知识总结(持续更新)

一、JDK、JRE、JVM三者之间的关系&#xff1f; 1. **JDK (Java Development Kit)**&#xff1a; JDK 是 Java 开发工具包&#xff0c;它包含了用于开发 Java 应用程序的所有必要工具和库。这包括 Java 编译器&#xff08;javac&#xff09;、Java 核心类库、开发工具&#x…...

缓存技术:加速应用,提高用户体验

本文总结前期某个系统中使用到的缓存使用经验—仅此而已,效果还不错。 缓存技术在系统架构设计中扮演着至关重要的角色,它不仅可以显著提高系统的性能,还可以改善用户体验。在本文章中,我们将探讨不同类型的缓存、缓存失效以及缓存淘汰等关键概念,帮助在后期的架构设计中…...

MySQL中分区与分表的区别

MySQL中分区与分表的区别 一、分区与分表的区别 分区和分表是在处理大规模数据时的两种技术手段&#xff0c;尽管它们的目标都是提升系统的性能和数据管理的效率&#xff0c;但它们的实现方式和应用场景略有不同。 1. 分区 分区是将一个大表分割为多个更小的子表&#xff0c…...

Redis主从复制集群的介绍及搭建

在现代的软件开发中&#xff0c;数据的可靠性和可用性是至关重要的。Redis&#xff0c;作为一个开源的、内存中的数据结构存储系统&#xff0c;以其出色的性能和灵活的数据结构&#xff0c;赢得了开发者们的广泛喜爱。而 Redis 的主从复制功能&#xff0c;更是为我们提供了一种…...

MAC M1芯片安装mounty读写移动硬盘中的文件

因为移动硬盘中的文件是微软公司NTFS格式&#xff0c;MAC只支持自己的APFS或者HFS&#xff0c;与微软的NTFS不兼容&#xff0c;所以需要第三方的软件来支持读写硬盘中的文件&#xff0c;经过一上午的折腾&#xff0c;最终选择安装mounty这个免费的第三方软件 工具网址连接&am…...

原生Js Canvas去除视频绿幕背景

Js去除视频背景 注&#xff1a; 这里的去除视频背景并不是对视频文件进行操作去除背景 如果需要对视频扣除背景并导出可以使用ffmpeg等库&#xff0c;这里仅作播放用所以采用这种方法 由于uniapp中的canvas经过封装&#xff0c;且 uniapp 的 drawImage 无法绘制视频帧画面&…...

Vue知识系列(1)每天10个小知识点

目录 系列文章目录知识点**1. Vue修饰符**的概念、作用、原理、特性、优点、缺点、区别、使用场景**2. 双向数据绑定**的概念、作用、原理、特性、优点、缺点、区别、使用场景**3. MVVM、MVC、MVP** 的概念、作用、原理、特性、优点、缺点、区别、使用场景**4. slot** 的概念、…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...