使用对象列表创建Avro Schema

2025/04/12

1. 概述

Apache Avro是一个数据序列化框架,它提供强大的数据结构和轻量级、快速的二进制数据格式。

在本教程中,我们将探讨如何创建一个Avro模式,当它转换为对象时,会包含其他对象的列表。

2. 目标

假设我们要开发一个表示父子关系的Avro模式,因此,我们需要一个包含Child对象列表的Parent类。

Java代码如下所示:

public class Child {
    String name;
}

public class Parent {
    List<Child> children;
}

我们的目标是创建一个Avro模式,将其结构转换为这些对象

在我们研究解决方案之前,让我们快速回顾一下Avro的一些基础知识:

  • Avro模式使用JSON定义
  • type字段指的是数据类型(例如,记录,数组,字符串)
  • fields数组定义记录的结构

3. 创建Avro Schema

为了正确说明Avro中的父子关系,我们需要使用record和array类型的组合。

该模式如下所示:

{
    "namespace": "cn.tuyucheng.taketoday.apache.avro.generated",
    "type": "record",
    "name": "Parent",
    "fields": [
        {
            "name": "children",
            "type": {
                "type": "array",
                "items": {
                    "type": "record",
                    "name": "Child",
                    "fields": [
                        {"name": "name", "type": "string"}
                    ]
                }
            }
        }
    ]
}

我们首先定义了一个Parent类型的记录,在Parent记录中,我们定义了一个children字段,该字段是一个数组类型,允许我们存储多个Child对象。数组类型的items属性详细说明了数组中每个元素部分的结构,在我们的例子中,这是一个Child记录。如我们所见,Child记录只有一个字符串类型的属性name。

4. 在Java中使用Schema

定义好Avro模式后,我们将使用它来生成Java类,当然,我们会使用Avro Maven插件来完成这项工作,以下是父pom文件中的配置:

<plugin>
    <groupId>org.apache.avro</groupId>
    <artifactId>avro-maven-plugin</artifactId>
    <version>1.11.3</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>schema</goal>
            </goals>
            <configuration>
                <sourceDirectory>src/main/java/cn/tuyucheng/taketoday/apache/avro/schemas</sourceDirectory>
                <outputDirectory>src/main/java</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

为了让Avro生成我们的类,我们需要运行Maven生成源命令(mvn clean generate-sources)或转到Maven工具窗口的插件部分并运行avro插件的avro:schema目标:

这样,Avro就会根据提供的schema在提供的namespace中创建Java类,namespace属性还会在生成的类顶部添加包名称。

5. 使用生成的类

新创建的类提供了设置方法,用于获取和设置子列表,如下所示:

@Test
public void whenAvroSchemaWithListOfObjectsIsUsed_thenObjectsAreSuccessfullyCreatedAndSerialized() throws IOException {
    Parent parent = new Parent();
    List<Child> children = new ArrayList();

    Child child1 = new Child();
    child1.setName("Alice");
    children.add(child1);

    Child child2 = new Child();
    child2.setName("Bob");
    children.add(child2);

    parent.setChildren(children);

    SerializationDeserializationLogic.serializeParent(parent);
    Parent deserializedParent = SerializationDeserializationLogic.deserializeParent();

    assertEquals("Alice", deserializedParent.getChildren().get(0).getName());
}

从上面的测试中,我们看到我们创建了一个新的Parent,我们可以这样做,或者使用builder()函数。这篇关于Avro默认值的文章演示了如何使用builder()模式。

然后,我们创建两个Child对象,并将它们添加到Parent的children属性中。最后,我们对该对象进行序列化和反序列化,并比较其中一个名称。

6. 总结

在本文中,我们研究了如何创建包含对象列表的Avro模式。此外,我们还详细介绍了如何定义带有子记录列表属性的父记录,这是一种在Avro中表示复杂数据结构的方法。此外,当我们需要处理对象集合或分层数据时,这种方法尤其有用。

最后,Avro模式非常灵活,我们可以配置它们来设置更复杂的数据结构。我们可以组合不同的类型和嵌套结构来复制我们的数据模型。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章