2015-09-05 51 views
2

我愿意将我的代码从mongojack迁移到支持新的异步mongo驱动程序的东西。然而,我发现编码/解码的新方法是通过Codec,我没有看到自己为我的模型中的每个类编写Codec。这就是为什么我宁愿写一个给定类创建一个Codec的图书馆。然而,我不知道如何,也不知道是否已经尝试实现相同的功能。 有没有一些库实现我想要的?如果不是,实现它的最好方法是什么。有没有什么方法可以自动创建Mongo编解码器?

(我知道我应该在那里使用CodecProvider地方,但我还是不知道从哪里开始)

+0

我不知道是什么做的编解码器,但你有没有看春节数据映射器? – chrylis

+2

我确实,但这不是我所需要的。新的mongo java驱动程序(版本3+)使我们有机会通过编解码器直接解析响应,而无需使用中间表示(DBObject)。但是你必须自己写(http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/)。我正在寻找一些自动编写这些编解码器的库,所以我不必手动执行。 – caeus

回答

3

是的,如果您使用杰克逊,您可以使用https://github.com/ylemoigne/mongo-jackson-codec中的mongo-jackson编解码器,它将自动为您处理。

+1

警告词:截至撰写本文时(2016-10-04),这个mongo-jackson-codec库存在一个严重的缺点,它只能通过完整的文档弥合mongo编解码器和jackson之间的差距,即它无法序列化在根级别的非文档BSON值。当您在'find'或'update'命令中构建查询'Bson'文档时(当使用本地Mongo Java驱动程序时),试图使用Jackson编解码器序列化类似'java.time.Instant'的值时, 。 –

3

嗯,我无法找到我需要这样的方向,我开始指向任何努力我拥有。它自动创建编解码器而无需使用中间表示,例如Document或DBObject。它使用Annotation Processing在编译时创建它们。

https://github.com/caeus/vertigo

希望它适用于任何人有同样的需求。

0

下面是我们如何解决这个问题(最终的结果是龙目岛,杰克逊和MongoDB之间的超光滑):

提供者:

public class JacksonCodecProvider implements CodecProvider { 
    private final ObjectMapper objectMapper; 

    public JacksonCodecProvider(final ObjectMapper bsonObjectMapper) { 
     this.objectMapper = bsonObjectMapper; 
    } 

    @Override 
    public <T> Codec<T> get(final Class<T> type, final CodecRegistry registry) { 

      return new JacksonCodec<>(objectMapper, registry, type); 

    } 
} 

以及编解码器本身:

class JacksonCodec<T> implements Codec<T> { 
    private final ObjectMapper objectMapper; 
    private final Codec<RawBsonDocument> rawBsonDocumentCodec; 
    private final Class<T> type; 

    public JacksonCodec(ObjectMapper objectMapper, 
         CodecRegistry codecRegistry, 
         Class<T> type) { 
     this.objectMapper = objectMapper; 
     this.rawBsonDocumentCodec = codecRegistry.get(RawBsonDocument.class); 
     this.type = type; 
    } 

    @Override 
    public T decode(BsonReader reader, DecoderContext decoderContext) { 
     try { 

      RawBsonDocument document = rawBsonDocumentCodec.decode(reader, decoderContext); 
      String json = document.toJson(); 
      return objectMapper.readValue(json, type); 
     } catch (IOException e) { 
      throw new UncheckedIOException(e); 
     } 
    } 

    @Override 
    public void encode(BsonWriter writer, Object value, EncoderContext encoderContext) { 
     try { 

      String json = objectMapper.writeValueAsString(value); 

      rawBsonDocumentCodec.encode(writer, RawBsonDocument.parse(json), encoderContext); 

     } catch (IOException e) { 
      throw new UncheckedIOException(e); 
     } 
    } 

    @Override 
    public Class<T> getEncoderClass() { 
     return this.type; 
    } 
} 

当合并与龙目岛和最新的杰克逊注解,它允许我们做这样的东西(几乎看起来像Java代码,呃?):

@JsonIgnoreProperties(ignoreUnknown=true) 
@JsonDeserialize(builder = Account.AccountBuilder.class) 
@Builder(toBuilder=true) 
@Value 
public class Account { 

    @JsonProperty private String _id; 
    @JsonProperty private long _version; 
    @JsonProperty private String organizationName; 

    @JsonPOJOBuilder(withPrefix = "") 
    public static final class AccountBuilder { 
    } 

} 

然后:

Account account = collection.find(eq("_id", id)).first(); 
System.out.println(account.getOrganizationName()); 
相关问题