Spark从入门到精通第十五课:RDD 转 DataFrame && SparkSQL读取json/parquet/mysql/hive

1、RDD转DataFrame

第一种方式:反射

package scala


import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SparkSession}

//定义一个样例类
case class Person(id:Int,name:String,age:Int,score:Double)

object SparkTest {

    def main(args: Array[String]) {
        val ss=SparkSession.builder()
            .master("local")
            .appName("firstSparkSQL")
            .getOrCreate()
        //使用sparkSQL的时候都要导入隐式转换
        import ss.implicits._
        val rdd1=ss.sparkContext.textFile("./words")  //读取文件
            .map(line =>{
            var word=line.split(",")    //拆分
            //给样例类传参
            Person(word(0).toInt,word(1).toString,word(2).toInt,word(3).toDouble)
        })
        //转成df
        val df=rdd1.toDF()
        /*
            show()方法默认显示20行数据,显示100行,则show(100)
            df.printSchema()  可打印表的结构信息
          */
        df.show()//打印表数据
        ss.stop()

        
        
    }
}

第二种方式:schema自动推导

package scala


import org.apache.spark.rdd.RDD
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Row, SparkSession}


object SparkTest {

  def main(args: Array[String]) {
    val ss = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .getOrCreate()

    import ss.implicits._ //sparkSQL都要导入隐式转换

    val rdd: RDD[String] = ss.sparkContext.textFile("./datas/tmp")
    //创建行式rdd
    val rows= rdd.map(one => {
      val word = one.split(",")
      Row(word(0).toInt,word(1).toString,word(2).toInt,word(3).toInt)
    })
    val schema=StructType(List(
      //指定schema
      StructField("id",IntegerType,true),
      StructField("name",StringType,true),
      StructField("age",IntegerType,true),
      StructField("score",IntegerType,true)
    ))
    //创建df
    val df: DataFrame = ss.createDataFrame(rows,schema)
    df.show()
    /*
      以下执行SQL
    */
    //步骤1:创建临时视图(只能在本session访问)
    df.createOrReplaceTempView("t1")
    //步骤2:查询并打印结果
    ss.sql("select * from t1 where age > 20 ").show()

    /*
      如果前面注册的视图很多,为了不混乱则可以重新创建一个sparksession
      但前面创建的所有临时视图就不能用了,除非用创建全局视图:
        frame.createGlobalTempView("t2")
      使用时:
         spark.sql("select * from global_temp_t2 where age > 20 ").show()
     */

    //停止sparksession
    ss.stop()
  }
}

2、SparkSQL读取json文件

package scala


import org.apache.spark.sql.{DataFrame, Row, SparkSession}


object SparkTest {

  def main(args: Array[String]) {
    val ss = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .getOrCreate()

    import ss.implicits._ //sparkSQL都要导入隐式转换
    /*
    第一种方式:
    val df=ss.read.json("./datas/tmp")

     */
    //第二种方式
    val df=ss.read.format("json").load("./datas/a.txt")

    df.show()//打印的时候直接就有了表结构
   
    //停止sparksession
    ss.stop()
  }
}

3、SparkSQL将json式的RDD/DataSet加载成DataFrame

A、将json式RDD加载成DataFrame

package scala

import org.apache.spark.sql.{SparkSession}


object SparkTest {

  def main(args: Array[String]) {
    val ss = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .getOrCreate()

    import ss.implicits._ //sparkSQL都要导入隐式转换

    val list=List("{'age':'1','name':'li4'}")
    val rdd=ss.sparkContext.makeRDD(list)
    val df=ss.read.json(rdd) //rdd加载成df
    df.show()
    ss.stop()
  }
}

B、将DataSet加载成DataFrame

package scala

import org.apache.spark.sql.{SparkSession}


object SparkTest {

  def main(args: Array[String]) {
    val ss = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .getOrCreate()

    import ss.implicits._ //sparkSQL都要导入隐式转换

    val list=List("{'age':'1','name':'li4'}")
    val ds = list.toDS()  //list转ds
    val df=ss.read.json(ds) //ds加载成df
    df.show()
    ss.stop()
  }
}

4、SparkSQL读取parquet数据

package scala

import org.apache.spark.sql.{DataFrame,SaveMode,SparkSession}

object SparkTest {

  def main(args: Array[String]) {
    val ss: SparkSession = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .getOrCreate()

    /*
      没有parquet格式的数据,我们利用json造一批
     */
    val df0: DataFrame = ss.read.format("json").load("./datas/a.txt")

    /*
      常用四种savemode:
        Append:追加     Overwrite:覆盖    Ignore:忽略       ErrorIfExists:存在即报错
        save:也可以保存到hdfs上,如果找不到hdfs在项目中加入hdfs配置文件
     */
    df0.write.mode(SaveMode.Overwrite)
      .format("parquet")
      .save("./datas/b.txt")
    /*
        第一种方式:
            val df=ss.read.format("parquet").load("./datas/b.txt")
     */
    //第二种方式
    val df: DataFrame = ss.read.parquet("./datas/b.txt")

    df.show()
    println(df.count)

    ss.stop()
  }
}

5、SparkSQL读取mysql数据

package scala

import java.util.Properties

import org.apache.spark.sql.{DataFrame, DataFrameReader, SparkSession}

object SparkTest {

  def main(args: Array[String]) {
    val ss: SparkSession = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .config("spark.sql.shuffle.partitions",1)
      .getOrCreate()
    /*
        第一种方式:
              val reader: DataFrameReader = ss.read.format("jdbc")
                  reader.option("url","jdbc:mysql://127.0.0.1:3306/d_student")
                  reader.option("driver","com.mysql.jdbc.Driver")
                  reader.option("user","root")
                  reader.option("password","123456")
                  reader.option("dbtable","t_student")
              val df: DataFrame = reader.load()
              df.show()
     */

    /*
        第二种方式:
                  val map=Map(
                    "url"         ->      "jdbc:mysql://127.0.0.1:3306/d_student",
                    "driver"      ->      "com.mysql.jdbc.Driver",
                    "user"        ->      "root",
                    "password"    ->      "123456",
                    "dbtable"     ->      "t_student"    //也可以是"(子查询)别名"
                  )
                val df: DataFrame = ss.read.format("jdbc").options(map).load()
     */
     //第三种方式 
     val ps=new Properties()
         ps.setProperty("user","root")
         ps.setProperty("password","123456")
     val df=ss.read.jdbc("jdbc:mysql://127.0.0.1:3306/d_student","t_student",ps)

    //单表查询
    df.createOrReplaceTempView("t1")    //创建临时视图(只能在本session访问)
    ss.sql("select * from t1 where age > 20 ").show()   
    
    /*
        多表查询,涉及到shuffle的操作会开启200个task来处理数据
        由spark.sql.shuffle.partitions参数控制,可以人为得调大调小     
      */
   val df2=ss.read.jdbc("jdbc:mysql://127.0.0.1:3306/d_student","t_grade",ps)
    df2.createOrReplaceTempView("t2")
    val df3: DataFrame = ss.sql("select * from t1 inner join t2 on t1.sid=t2.stu_id where t2.score>60")
    df3.show()
        
     //将结果保存到mysql中  
    df3.write.mode(SaveMode.Overwrite)
        .jdbc("jdbc:mysql://127.0.0.1:3306/d_student","temp",ps)


    /*
      如果前面注册的视图很多,为了不混乱则可以重新创建一个sparksession
      但前面创建的所有临时视图就不能用了,除非之前创建的是全局视图:
        frame.createGlobalTempView("t2")
      使用时:
         spark.sql("select * from global_temp_t2 where age > 20 ").show()
     */    
  }
}

6、读取hive中的数据

参考:
    https://blog.csdn.net/pengzonglu7292/article/details/89682724

1、在spark的conf目录新建一个hive-site.xml,在该配置文件中加入metastore的端口即可,如下
    <configuration>
        <property>
            <name>hive.metastore.uris</name>
            <value>thrift://Linux001:9083</value>
        </property>
    </configuration>

2、启动HDFS & Hive && metastore


3、在main/resources/目录下加入hive-site.xml文件

4、代码

package scala

import org.apache.spark.sql.{SparkSession}

object SparkTest {

  def main(args: Array[String]) {
    val ss: SparkSession = SparkSession.builder()
      .master("local")
      .appName("SparkSQLApp")
      .enableHiveSupport()  //开启hive支持
      .getOrCreate()

    /*
        以下执行hive sql
     */
    ss.sql("use default") //使用default数据库
    //创建表
    ss.sql("create table jizhan_raw(" +
      "record_time String, imei String, cell String, ph_num int, " +
      "call_num int, drop_num int, duration int,drop_rate int, " +
      "net_type String, erl int )" +
      "row format delimited fields terminated by ','")
    //插入数据
    ss.sql("load data local inpath '/opt/apps/data/jizhan.csv' " +
      "overwrite into table jizhan_raw")
    //查询记录总条数
    ss.sql("select count(*) from jizhan_raw ").show()
    //创建结果表
    ss.sql("create table jizhan_result(imei String,drop_num int,duration int," +
      " drop_rate double )row format delimited fields terminated by ','")
    //往结果表中插入结果数据
    ss.sql("insert into  jizhan_result select imei,sum(drop_num) s_drop," +
      "sum(duration)s_dura,sum(drop_num)/sum(duration) s_rate from jizhan_raw" +
      " group by imei order by s_rate desc limit 10")
    //查看结果
    ss.sql("select * from jizhan_result").show()
    ss.stop()
  }
}
    


4、maven--->clean(清除之前的jar包信息)--->package(打包)------>上传集群----->运行

运行命令:
spark-submit 
--master local[*] 
--class scala.SparkTest 
/opt/apps/spark-2.3.1-bin-hadoop2.6/user_jar/MySpark-1.0-SNAPSHOT-jar-with-dependencies.jar



==================================================================
如果要在idea本地操作hive中的数据:
    1、core-site.xml/hdfs-site.xml/hive-site.xml中的文件放到idea的resources源中。
    2、数据文件放在idea本地的目录下。
    3、代码中数据文件的路径记得更改。

#如果连接虚拟机特别慢
    vi /etc/ssh/sshd_config
        添加  UseDns  no

 

 

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二百四十九先森

你的打赏是我努力的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值