[大数据]连载No15之 Spark Sql

本次总结图如下

Spark Sql介绍
1、Shark是基于Spark计算框架之上的且兼容Hive语法的SQL执行引擎 ,但是底层依赖于Hive的解析器,查询优化器,正是由于Shark的整体设计架构对Hive的依赖性太强,难以支持其长远发张,无法满足Spark的一站式解决大数据处理问题
2、Hive是Shark的前身,Shark是SparkSql的前身
3、相对于Shark,SparkSQL的优势
   a、完全脱离了Hive的限制
   b、支持原生的RDD
   c、能够在Scala中写Sql语句,支持简单的Sql语法检查,能够在Scala中写Hive语句访问Hive数据,并将结果取回作为RDD使用

创建SparkSql之DataFrame方式
1、通过读取json格式文件
2、通过一个JSON格式RDD
3、普通RDD转换DataFrame
   a、反射方式(不建议),修改类或者增加类,麻烦
       》自定义类必须是public
       》自定义类必须是可序列化
       》RDD转化成DataFramed的时候,DF中列的顺序会根据自定义类的字段名按照字典序进行排列
   b、动态创建schedule方式
       》可以将列信息存储到外部文件
4、通过读取parquet文件 
   a、数据输出
   b、Parquet格式文件能够自动推断分区  
5、通过读取mysql数据创建        
6、通过读取Hive中的数据
   Spark on Hive整合说明:Hive提供了一个metaStore服务,直接开启这个服务,spark Sql连接这个服务,就能读取数据
   一:开启Hive的metaSotre服务 hive --service metaStore
   二:在Spark集群客户端节点Spark的安装包目录conf,创建一个hive-site.xml
    <configuration>
<property>
  <name>hive.metastore.uris</name>
    <value>thrift://hadoop1:9083</value>
      </property>
     </configuration>
    三:开启spark shell测试是否成功


代码实现

SparkConf conf =new SparkConf().setAppName("DataFrameCreate").setMaster("local");
JavaSparkContext sc =new JavaSparkContext(conf);

SQLContext sqlContext =new SQLContext(sc);

DataFrame df=sqlContext.jsonFile("people.json");

df.registerTempTable("tb");

String sql= "select * from tb ";
DataFrame result=sqlContext.sql(sql);
result.show();

// SELECT age FROM tb
result.select("age").show();

// SELECT name|'_1',age as _age FROM tb
result.select(result.col("name"),result.col("age").plus(10).alias("_age")).show();

// SELECT * FROM tb WHERE age > 20
result.filter(result.col("age").gt(20)).show();


/**
 * 示例一: 通过读取json文件创建DataFrame
 * 读取数据文件,转成Dataframe
 */
DataFrame people =sqlContext.jsonFile("people.json");

//相当于 select age+20 as _age , name from people
people.select(people.col("age").plus(20).alias("_age"),people.col("name")).show();

//相当于 select * from  people where age >0
people.filter(people.col("age").gt(20)).show();



/**
 *示例二: 通过jsonRDD 创建DataFrame
 * 创建一个本地的集合  集合中元素的格式   json        类型String
 */
List<String> nameList = Arrays.asList(
        "{'name':'zhangsan', 'age':55}",
        "{'name':'lisi', 'age':30}",
        "{'name':'lisisi', 'age':30}",
        "{'name':'wangwu', 'age':19}");

List<String> scoreList = Arrays.asList(
        "{'name':'zhangsan','score':100}",
        "{'name':'lisi','score':99}" );

/**
 * 集合转成RDD
 */
JavaRDD<String> nameRdd=sc.parallelize(nameList);
JavaRDD<String> scoreRdd=sc.parallelize(scoreList);

/**
 * RDD转成DataFrame
 */
DataFrame nameDf =sqlContext.jsonRDD(nameRdd);
DataFrame scoreDf =sqlContext.jsonRDD(scoreRdd);

/**
 * 使用 DataFrame 对象联合查询
 */
nameDf.join(scoreDf,nameDf.col("name").$eq$eq$eq(scoreDf.col("name")))
.select(nameDf.col("name"),nameDf.col("age"),scoreDf.col("score")).show();

System.out.println("---------------------------");


/**
 * 使用sql 方式查询
 */
nameDf.registerTempTable("nameTB");
scoreDf.registerTempTable("scoreTB");

sql ="select * from nameTB  n inner join scoreTB s on  n.name =s.name";
sqlContext.sql(sql).show();


/**
 * 示例三: 使用动态创建schedule方式
 */
JavaRDD<String> peopelStr=sc.textFile("Peoples.txt");
JavaRDD<Row> rowJavaRDD = peopelStr.map(new Function<String, Row>() {
    @Override
    public Row call(String s) throws Exception {
        String [] lines= s.split(",");
        return RowFactory.create(Integer.valueOf(lines[0]),lines[1],Integer.valueOf(lines[2]));
    }
});

/**
 * 查询数据库 id_int_true, name_String_true, age_int_true
 *
 * id、Int、true
 *
 * 我们可以将每列的信息存储到外部文件或者数据库中,在创建schema的时候去外部文件或者数据库中查询
 修改每一列的列名以及列的类型的时候就变的非常方便了
 */
ArrayList<StructField>  structFields=new ArrayList<>();
structFields.add(DataTypes.createStructField("id",DataTypes.IntegerType,true));
structFields.add(DataTypes.createStructField("name",DataTypes.StringType,true));
structFields.add(DataTypes.createStructField("age",DataTypes.IntegerType,true));

/**
 *  构建StructType,用于最后DataFrame元数据的描述
 */
StructType structType=DataTypes.createStructType(structFields);

/**
 * 通过schedule+RDD 来构造DataFrame
 */
DataFrame rowDF=sqlContext.createDataFrame(rowJavaRDD,structType);
rowDF.show();

rowDF.registerTempTable("peotext");

System.out.println("------------------");
sqlContext.sql("select * from peotext").show();

//输出流
sqlContext.sql("select * from peotext").write().format("json").save("ttttt.text");


/**
 * 示例五:读取数据库方式
 */
DataFrameReader reader =sqlContext.read().format("jdbc") ;
reader.option("url","jdbc:mysql://192.168.0.153:3306/rb?useUnicode=true&characterEncoding=utf-8");
reader.option("dirver","com.mysql.jdbc.Driver");
reader.option("user","root");
reader.option("password","a1234567");
reader.option("dbtable","role");

DataFrame mysqlDf =reader.load();

mysqlDf.show();

sc.stop();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

源14

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值