最新的Avro编译器(1.8.2)为基于dates logical types的实现生成Joda-Time的java源代码。如何配置Avro编译器以生成使用Java 8日期时间API的源?
答案 0 :(得分:12)
目前(avro 1.8.2)这是不可能的。它是硬编码生成Joda日期/时间类。
当前的master
分支已切换到Java 8,并且有open issue(Pull Request)来添加生成java.time.*
类型的类的功能。
我不知道任何类型的发布时间表,不幸的是master
中的任何内容。如果您有冒险精神,可以将补丁应用于1.8.2
,因为理论上它应该兼容。序列化/反序列化时的基础类型仍然是整数和长整数。
答案 1 :(得分:5)
您需要创建自己的Conversion以支持java-8日期时间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));
序列化&amp;反序列化你应该设置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());
答案 2 :(得分:1)
使用avro 1.9.2,您可以使用例如date代表LocalDate
:
{
"name": "Transaction",
"type": "record",
"fields": [
{
"name": "time",
"type": {
"type": "int",
"logicalType": "date"
}
},
有关其他类型,请参见Logical Types。
答案 3 :(得分:1)
AVRO 1.10添加了对LocalDateTime
的支持,请参见Apache Avro™ 1.10.0 Specification
答案 4 :(得分:1)
1.9.0
< 1.10.0
<dateTimeLogicalTypeImplementation>jsr310</dateTimeLogicalTypeImplementation>
进入 configuration
部分。1.10.0