[英]Avro with Java 8 dates as logical type
目前(avro 1.8.2)這是不可能的。 生成 Joda 日期/時間類是硬編碼的。
當前的master
分支已切換到 Java 8,並且有一個未解決的問題(使用Pull Request )以添加生成具有java.time.*
類型的類的能力。
不幸的是,我不知道當前master
任何內容的發布時間表。 如果你喜歡冒險,你可以將補丁應用到1.8.2
,因為理論上它應該都是兼容的。 序列化/反序列化時的底層基本類型仍然是整數和長整數。
您需要創建自己的Conversion來支持 java-8 date-time api,下面是java.time.LocalDate
的轉換:
class Java8LocalDateConversion extends Conversion<LocalDate> {
@Override
public Class<LocalDate> getConvertedType() {
return LocalDate.class;
}
@Override
public String getLogicalTypeName() {
// v--- reuse the logical type `date`
return "date";
}
@Override
// convert LocalDate to Integer
public Integer toInt(LocalDate value, Schema schema, LogicalType type) {
return (int) value.toEpochDay();
}
@Override
// parse LocalDate from Integer
public LocalDate fromInt(Integer value, Schema schema, LogicalType type) {
return LocalDate.ofEpochDay(value);
}
}
邏輯類型可以在 avro 中重用,因此您可以使用現有的date
邏輯類型,例如:
Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));
對於序列化和反序列化,您應該設置GenericData
它將找到您自己的轉換,例如:
//serializing
DatumWriter<T> out = new SpecificDatumWriter<>(schema, data());
// deserializing
DatumReader<T> in = new SpecificDatumReader<>(schema, schema, data());
private SpecificData data() {
SpecificData it = new SpecificData();
it.addLogicalTypeConversion(new Java8LocalDateConversion());
return it;
}
如果不想每次都配置GenericData
,可以改用全局GenericData
,例如:
// register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());
1.9.0
< 1.10.0
<dateTimeLogicalTypeImplementation>jsr310</dateTimeLogicalTypeImplementation>
到configuration
部分。1.10.0
AVRO 1.10 添加了對LocalDateTime
支持,請參閱Apache Avro™ 1.10.0 規范
Avro v1.11.0 TimeConversions內置支持 Java 8 時間類,例如LocalDate
、 Instant
等。 TimeConversions
必須注冊到SpecificData
類或其子類,例如ReflectData
。 以下是如何使用TimeConversions
的完整示例:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account
{
private int id;
private LocalDate createdOn;
public static void main(String[] args) throws IOException
{
// create schema from POJO Account class
ReflectData reflectData = ReflectData.get();
reflectData.addLogicalTypeConversion(new TimeConversions.DateConversion());
Schema schema = reflectData.getSchema(Account.class);
System.out.println("Schema in JSON:\n" + schema + "\n");
// create avro writer
DatumWriter<Account> datumWriter = new ReflectDatumWriter<>(schema);
DataFileWriter<Account> dataFileWriter = new DataFileWriter<>(datumWriter);
// dataFileWriter.setCodec(CodecFactory.snappyCodec()); // for compression
dataFileWriter.create(schema, new File("accounts.avro"));
dataFileWriter.append(new Account(123, LocalDate.of(2001, 1, 1)));
dataFileWriter.append(new Account(234, LocalDate.of(2002, 2, 2)));
dataFileWriter.close();
// create avro reader
DatumReader<Account> datumReader = new ReflectDatumReader<>(schema);
DataFileReader<Account> dataFileReader = new DataFileReader<>(new File("accounts.avro"), datumReader);
dataFileReader.forEach(System.out::println);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.