AVRO是Apache提供的一套用于进行序列化和RPC的机制
之前我们在使用redis存储数据的时候,把对象转化为json 的过程,就可以称为序列化。
序列化: 将对象按照指定的规则转化为指定形式的数据
意义: 当一个项目由多种语言开发的时候,各种语言之间的数据怎么互通?就可以使用序列化来实现这个目标,把数据转化为与语言无关的数据(数字,布尔值,字符或字符串)。AVRO就是在json基础上对对象进行转化 .
远程过程调用,指的是允许程序员在一台服务器上远程调用另一台服务器上的方法而不用显式地实现这个过程,适用于分布式系统之间的通信 。
1.创建maven项目,在pom文件中导入依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tedu</groupId>
<artifactId>avro</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-rc-1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.8.2</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.在main下创建一个文件夹名为avro,在里面创建一个.avsc文件,文件名随便取
在文件中输入:
// AVRO将对象转化为json,所以需要定义json格式
{
"namespace":"cn.tedu.pojo", // 等价于Java中的package
"type":"record", // record等价于Java中的class
"name":"User", // 类名叫User
"fields":
[
{"name":"username","type":"string"}, // String username
{"name":"age","type":"int"}, // int age
{"name":"gender","type":"string"},// String gender
{"name":"height","type":"double"}, // double height
{"name":"weight","type":"double"} // double weight
]
}
3.点击右边maven,找到avro,lifecycle中的compile,点击后开始下载包信息。
下载完成后,就可以在你的maven中看见了一个新的user类,这个类就是avro给你自动生成的,类的具体信息都是根据上面的 .avro文件中的信息完成的。
4.创建对象的5种方式:
// 创建对象
// AVRO中,不允许属性值为null
@Test
public void create() {
// 方式一:创建对象并赋值
User u1 = new User();
u1.setUsername("Lily");
u1.setAge(19);
u1.setGender("female");
u1.setHeight(168.0);
u1.setWeight(68.8);
System.out.println(u1);
// 方式二:调用含参构造来创建对象
User u2 = new User("Alex", 17,
"male", 185.2, 70.4);
System.out.println(u2);
// 方式三:指定属性赋值 - 适合于反射或者加载文件中的数据
User u3 = new User();
u3.put("username", "Helen");
u3.put("age", 15);
u3.put("gender", "female");
u3.put("height", 165.2);
u3.put("weight", 58.8);
System.out.println(u3);
// 方式四:序号赋值 - 序列化产生的数据会更少
User u4 = new User();
u4.put(0, "John");
u4.put(1, 25);
u4.put(2, "male");
u4.put(3, 187.7);
u4.put(4, 65.9);
System.out.println(u4);
// 方式五:建造者模式 - 仿造
// 仿照u4创建对象,其中只有username不一样
User u5 = User.newBuilder(u4)
.setUsername("Jack").build();
System.out.println(u5);
}
5.序列化
// 序列化
@Test
public void serial() throws IOException {
// 创建对象
User u1 = new User("Amy", 15, "female", 157.2, 58.8);
User u2 = new User("Jack", 18, "male", 187.2, 78.8);
User u3 = new User("Tom", 14, "male", 158.1, 65.2);
// 创建序列化流
DatumWriter<User> dw =
new SpecificDatumWriter<>(User.class);
// 创建文件流
DataFileWriter<User> dfw = new DataFileWriter<>(dw);
// 指定文件
dfw.create(User.SCHEMA$, new File("D:\\user.data"));
// 序列化对象
dfw.append(u1);
dfw.append(u2);
dfw.append(u3);
// 关流
dfw.close();
}
@Test
public void deserial() throws IOException {
// 创建反序列化流
DatumReader<User> dr = new SpecificDatumReader<>(User.class);
// 创建文件流
DataFileReader<User> dfr = new DataFileReader<>(
new File("D:\\user.data"), dr);
// 反序列化对象 - 为了方便操作,将流定义为迭代器形式
while (dfr.hasNext()) {
User u = dfr.next();
System.out.println(u);
}
// 关流
dfr.close();
}