2015-09-05 31 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()); 
相關問題