生成dataset的几种方式

1.常用的方式通过sparksession读取外部文件或者数据生成dataset(这里就不讲了)
  注: 生成Row对象的方法提一下:RowFactory.create(x,y,z),取Row中的数据使用row.getAs("列名")来获取对应的列值或者row.getInt(0),row.getString(1)(但这个要注意顺序)

   

2.通过调用createDataFrame生成Dataset
通过反射的方式将非json格式的RDD转换成DataFrame(不建议使用)

自定义类要可序列化
自定义类的访问级别是Public
RDD转成DataFrame后会根据映射将字段按Assci码排序
将DataFrame转换成RDD时获取字段两种方式,一种是df.getInt(0)下标获取(不推荐使用),另一种是df.getAs(“列名”)获取(推荐使用)
关于序列化问题:
             1.反序列化时serializable 版本号不一致时会导致不能反序列化。
             2.子类中实现了serializable接口,父类中没有实现,父类中的变量不能被序列化,序列化后父类中的变量会得到null。
             注意:父类实现serializable接口,子类没有实现serializable接口时,子类可以正常序列化
            3.被关键字transient修饰的变量不能被序列化。
            4.静态变量不能被序列化,属于类,不属于方法和对象,所以不能被序列化。
           另外:一个文件多次writeObject时,如果有相同的对象已经写入文件,那么下次再写入时,只保存第二次写入的引用,读取时,都是第一次保存的对象。

 1 /**方法1
 2 * 注意:
 3 * 1.自定义类必须是可序列化的
 4 * 2.自定义类访问级别必须是Public
 5 * 3.RDD转成DataFrame会把自定义类中字段的名称按assci码排序
 6 */
 7 SparkConf conf = new SparkConf();
 8 conf.setMaster("local").setAppName("RDD");
 9 JavaSparkContext sc = new JavaSparkContext(conf);
10 SQLContext sqlContext = new SQLContext(sc);
11 JavaRDD<String> lineRDD = sc.textFile("sparksql/person.txt");
12 JavaRDD<Person> personRDD = lineRDD.map(new Function<String, Person>() {
13 
14     /**
15     * 
16     */
17     private static final long serialVersionUID = 1L;
18 
19     @Override
20     public Person call(String s) throws Exception {
21           Person p = new Person();
22           p.setId(s.split(",")[0]);
23           p.setName(s.split(",")[1]);
24           return p;
25     }
26 });
27 /**
28 * 传入进去Person.class的时候,sqlContext是通过反射的方式创建DataFrame
29 * 在底层通过反射的方式获得Person的所有field,结合RDD本身,就生成了DataFrame
30 */
31 DataFrame df = sqlContext.createDataFrame(personRDD, Person.class); 
32 
33 class Person implements Serializable {
34     private static final long serialVersionUID = -6907013906164009798L;
35     private String Id;
36     private String name;
37 
38 
39 
40     public void setId(String appId) {
41         this.appId = appId;
42     }
43 
44     public String getId() {
45         return appId;
46     }
47 
48     public String getname() {
49         return detail;
50     }
51 
52     public void setname(String detail) {
53         this.detail = detail;
54     }
55 }
 1 //方法2:
 2 JavaRDD<String> lineRDD = sc.textFile("./sparksql/person.txt");
 3 /**
 4  * 转换成Row类型的RDD
 5  */
 6 JavaRDD<Row> rowRDD = lineRDD.map(new Function<String, Row>() {
 7 
 8     /**
 9      * 
10      */
11     private static final long serialVersionUID = 1L;
12 
13     @Override
14     public Row call(String s) throws Exception {
15           return RowFactory.create(//这里字段顺序一定要和下边 StructField对应起来
16                 String.valueOf(s.split(",")[0]),
17                 String.valueOf(s.split(",")[1]),
18     );
19     }
20 });
21 /**
22  * 动态构建DataFrame中的元数据,一般来说这里的字段可以来源自字符串,也可以来源于外部数据库
23  */
24 List<StructField> asList =Arrays.asList(//这里字段顺序一定要和上边对应起来
25     DataTypes.createStructField("id", DataTypes.StringType, true),
26     DataTypes.createStructField("name", DataTypes.StringType, true)
27 );
28 StructType schema = DataTypes.createStructType(asList);
29 /*
30   StructType schema = new StructType(new StructField[]{
31                         new StructField("id", DataTypes.StringType, false, Metadata.empty()),
32                         new StructField("name", DataTypes.StringType, false, Metadata.empty()),
33             });
34 */
35 //DataFrame df = sqlContext.createDataFrame(List<Row> ,schema)这个方法也可以
36 DataFrame df = sqlContext.createDataFrame(rowRDD, schema);
 1 //方法3
 2 public static class Person implements Serializable {
 3   private String name;
 4   private int age;
 5 
 6   public String getName() {
 7     return name;
 8   }
 9 
10   public void setName(String name) {
11     this.name = name;
12   }
13 
14   public int getAge() {
15     return age;
16   }
17 
18   public void setAge(int age) {
19     this.age = age;
20   }
21 }
22 
23 // Create an instance of a Bean class
24 Person person = new Person();
25 person.setName("Andy");
26 person.setAge(32);
27 
28 // Encoders are created for Java beans
29 Encoder<Person> personEncoder = Encoders.bean(Person.class);
30 Dataset<Person> javaBeanDS = spark.createDataset(
31   Collections.singletonList(person),
32   personEncoder
33 );
34 javaBeanDS.show();
35 // +---+----+
36 // |age|name|
37 // +---+----+
38 // | 32|Andy|
39 // +---+----+
40 
41 // Encoders for most common types are provided in class Encoders
42 Encoder<Integer> integerEncoder = Encoders.INT();
43 Dataset<Integer> primitiveDS = spark.createDataset(Arrays.asList(1, 2, 3), integerEncoder);
44 Dataset<Integer> transformedDS = primitiveDS.map(
45     (MapFunction<Integer, Integer>) value -> value + 1,
46     integerEncoder);
47 transformedDS.collect(); // Returns [2, 3, 4]
48 
49 // DataFrames can be converted to a Dataset by providing a class. Mapping based on name
50 String path = "examples/src/main/resources/people.json";
51 Dataset<Person> peopleDS = spark.read().json(path).as(personEncoder);
52 peopleDS.show();
53 // +----+-------+
54 // | age|   name|
55 // +----+-------+
56 // |null|Michael|
57 // |  30|   Andy|
58 // |  19| Justin|
59 // +----+-------+

 

posted @ 2018-10-19 09:38  一直爬行的蜗牛牛  阅读(5992)  评论(0编辑  收藏  举报