java - 有什么方法可以自动创建 Mongo 编解码器吗?

标签 java mongodb asynchronous codec

我愿意将我的代码从 mongojack 迁移到支持新的异步 mongo 驱动程序的代码。然而,我发现编码/解码的新方法是通过 Codec,我不认为自己为模型中的每个类都编写了一个 Codec。这就是为什么我宁愿编写一个库,给定一个类创建一个 Codec。但是我不知道怎么做,也不知道是否已经有人在努力实现同样的目标。 是否有一些库可以实现我想要的?如果不是,实现它的最佳方法是什么。

(我知道我应该在那里的某个地方使用 CodecProvider,但我仍然不知道从哪里开始)

最佳答案

这是我们解决这个问题的方法(最终结果在 Lombok、Jackson 和 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 和最新的 Jackson 注释时,它允许我们做这样的事情(看起来不像 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());

关于java - 有什么方法可以自动创建 Mongo 编解码器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417267/

相关文章:

java.lang.NoClassDefFoundError : com/mongodb/connection/BufferProvider 错误

javascript - 将同步功能转换为异步功能

java - JTextArea 中的 Unicode 字符未正确显示

java - 与android线程相关的looper、handler等术语是什么?这些类之间有何关系?

java - 如何使用 APV PDF 查看器

java - NetBeans 中的collectd 插件

mongodb - 将 GuidRepresentation.Standard 与 MongoDB 一起使用

mongodb - 关于Morphia版本(乐观锁)

django - 为Django项目选择一个好的异步解决方案

Python Asyncio 阻塞协程