2015-09-05 6 views
2

Я готов перенести свой код с mongojack на то, что поддерживает новый драйвер async mongo. Тем не менее, я обнаружил, что новый способ кодирования/декодирования - Codec s, и я не вижу, чтобы я писал Codec для каждого класса моей модели. Вот почему я бы предпочел написать lib, который задал класс, создающий Codec. Однако я не знаю, как и не знаю, есть ли там какие-то усилия, пытающиеся добиться того же. Есть ли какие-то библиотеки, которые достигают того, чего я хочу? если нет, то какой лучший подход к его достижению.Есть ли способ создать монго-кодеки автоматически?

(я знаю, что, вероятно, следует использовать CodecProvider где-то там, но я до сих пор не знаю, с чего начать)

+0

Я не уверен, что делать кодеки, но вы смотрели на картографов Spring Data? – chrylis

+2

У меня действительно, но это не то, что мне нужно. Новый драйвер mongo java (версия 3+) дает нам возможность проанализировать ответ непосредственно на наши классы домена без использования промежуточных представлений (DBObject) через Codecs. Но вы должны сами написать их (http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/). Я ищу библиотеку, которая автоматически записывает эти кодеки, поэтому мне не нужно делать это вручную. – caeus

ответ

3

Да, если вы используете Джексон, вы можете использовать кодек mongo-jackson от https://github.com/ylemoigne/mongo-jackson-codec, который будет обрабатывать его автоматически для вас.

+1

Слово предупреждения: на момент написания этой статьи (2016-10-04) эта библиотека mongo-jackson-codec имеет серьезный недостаток в том, что она может только преодолеть разрыв между кодеками mongo и jackson через полные документы, то есть не может сериализовать не-документальные значения BSON на корневом уровне. Это ограничение вступит в силу при попытке использовать кодек Jackson для сериализации таких значений, как 'java.time.Instant' при создании запросов' Bson' документов в вашей команде 'find' или' update' (при использовании родных драйверов Mongo Java) , –

3

Ну, я не смог найти каких-либо усилий, указывая в направлении мне нужно, поэтому я начал свою своя. Он автоматически создает кодеки без использования промежуточных представлений, таких как Document или DBObject. Он использует обработку аннотаций для их создания во время компиляции.

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; 
    } 
} 

В сочетании с Lombok и последними аннотациями Джексона, это позволяет нам делать такие вещи (вряд ли выглядит как 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()); 
Смежные вопросы