1.步骤分析
Michael, 29
Andy, 30
Justin, 19
// 创建一个RDD
JavaRDD<String> peopleRDD = spark.sparkContext()
// textFile参数 (文件路径 , 切片数)
.textFile("F:/Code/Spark/SparkSql/SparkSql/src/main/resources/people.txt", 1)
.toJavaRDD();
- 定义DataFrame 的列名(字段名) 使用空格分隔
String fieldNames = "name age";
- 创建存储字段(每一列)对象的集合
List<StructField> fields = new ArrayList<>();
- 根据列名生成相应的字段对象 , 并存入 fields 集合中
for (String fieldName : fieldNames.split(" ")) {
StructField field = DataTypes
// 参数 (字段名 , 字段值类型 , 字段值是否可以为空)
.createStructField(fieldName, DataTypes.StringType , true);
// 将创建的字段结构对象存入集合中
fields.add(field);
}
- // 创建结构类型对象 , 封装了DataFame 所有的列(字段/属性) 的对象
// 这个对象就代表了 DataFrame的结构
// createStructType(集合 / 数组) 要求必须是 StructField
StructType schema = DataTypes.createStructType(fields);
- // 将原本RDD中的数据 封装到 ROW 中
// 原本的数据 : Michael, 29
// 封装后的数据 : ROW(Michael , 29)
JavaRDD<Row> rowRDD = peopleRDD.map((Function<String, Row>) lines -> {
// 对数据进行分割
String[] attributes = lines.split(",");
return RowFactory.create(attributes[0], attributes[1].trim());
});
- // 将RDD 转化为 自定义结构的DataFrame
Dataset<Row> peopleDataFrame = spark.createDataFrame(rowRDD, schema);
/* 查询数据 */
// 1.创建临时表
peopleDataFrame.createOrReplaceTempView("people");
// 2. 执行Sql 语句进行查询
Dataset<Row> result = spark.sql("SELECT name FROM people");
// 3.显示查询结果
result.show();
// 将 name 列的数据转化为 Dataset类型的
// Map的参数 (RDD , 编码器对象)
Dataset<String> nameDS = result.map(
// getString(int colIndex)
(MapFunction<Row, String>) row -> "name:" + row.getString(0),
Encoders.STRING()
);
// 显示数据
nameDS.show();
2.完整源代码
// 指定 DataFrame 的结构
private void runProgrammaticSchemaExample(SparkSession spark) {
/**
* people.txt
* Michael, 29
* Andy, 30
* Justin, 19
*/
// 创建一个RDD
JavaRDD<String> peopleRDD = spark.sparkContext()
.textFile("F:/Code/Spark/SparkSql/SparkSql/src/main/resources/people.txt", 1)
.toJavaRDD();
// 创建DataFrame 的结构
// 1.定义DataFrame 的列名(字段名) 使用空格分隔
String fieldNames = "name age";
// 2.创建存储字段(每一列)对象的集合
List<StructField> fields = new ArrayList<>();
// 3.根据列名生成相应的字段对象 , 并存入 fields 集合中
for (String fieldName : fieldNames.split(" ")) {
StructField field = DataTypes
// 参数 (字段名 , 字段值类型 , 字段值是否可以为空)
.createStructField(fieldName, DataTypes.StringType , true);
// 将创建的字段结构对象存入集合中
fields.add(field);
}
// 创建结构类型对象 , 封装了DataFame 所有的列(字段/属性) 的对象
// 这个对象就代表了 DataFrame的结构
// createStructType(集合 / 数组) 要求必须是 StructField
StructType schema = DataTypes.createStructType(fields);
// 将原本RDD中的数据 封装到 ROW 中
// 原本的数据 : Michael, 29
// 封装后的数据 : ROW(Michael , 29)
JavaRDD<Row> rowRDD = peopleRDD.map((Function<String, Row>) lines -> {
// 对数据进行分割
String[] attributes = lines.split(",");
return RowFactory.create(attributes[0], attributes[1].trim());
});
// 将RDD 转化为 自定义结构的DataFrame
Dataset<Row> peopleDataFrame = spark.createDataFrame(rowRDD, schema);
/* 查询数据 */
// 1.创建临时表
peopleDataFrame.createOrReplaceTempView("people");
// 2. 执行Sql 语句进行查询
Dataset<Row> result = spark.sql("SELECT name FROM people");
// 3.显示查询结果
result.show();
// 将 name 列的数据转化为 Dataset类型的
// Map的参数 (RDD , 编码器对象)
Dataset<String> nameDS = result.map(
// getString(int colIndex)
(MapFunction<Row, String>) row -> "name:" + row.getString(0),
Encoders.STRING()
);
// 显示数据
nameDS.show();
}