Есть ли способ автоматического создания кодеков Mongo?
Я готов перенести мой код из mongojack во что-то, что поддерживает новый драйвер async mongo. Тем не менее, я считаю, что новый способ кодирования / декодирования Codec
и я не вижу себя пишущим Codec
для каждого класса в моей модели. Вот почему я предпочел бы написать библиотеку, которая дает класс создает Codec
, Однако я не знаю как, и при этом я не знаю, есть ли уже какое-то усилие, пытающееся достигнуть того же самого. Есть ли какие-то либы, которые достигают того, чего я хочу? если нет, каков наилучший подход для достижения этого.
(Я знаю, что я должен использовать CodecProvider
где-то там, но я до сих пор не знаю с чего начать)
3 ответа
Да, если вы используете Джексон, вы можете использовать кодек Монго-Джексона с https://github.com/ylemoigne/mongo-jackson-codec который будет обрабатывать его автоматически для вас.
Вот как мы решаем эту проблему (конечный результат - супер гладкий между Ломбоком, Джексоном и 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());
Ну, я не мог найти никакого усилия, указывающего направление, в котором я нуждался, поэтому я начал свое собственное. Он создает кодеки автоматически без использования промежуточных представлений, таких как Document или DBObject. Он использует обработку аннотаций для их создания во время компиляции.
https://github.com/caeus/vertigo
Надеюсь, что это работает для всех с такими же потребностями.