MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Baca BSON (mongoDB) ke dalam POJO menggunakan GSON dan TypeAdapter

Saya menyelesaikannya menggunakan CustomizedTypeAdapterFactory. Lihat pertanyaan ini

Pada dasarnya pertama-tama tulis adaptor yang disesuaikan:

public abstract class CustomizedTypeAdapterFactory<C>
        implements TypeAdapterFactory
{
    private final Class<C> customizedClass;

    public CustomizedTypeAdapterFactory(Class<C> customizedClass) {
        this.customizedClass = customizedClass;
    }

    @SuppressWarnings("unchecked") // we use a runtime check to guarantee that 'C' and 'T' are equal
    public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        return type.getRawType() == customizedClass
                ? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type)
                : null;
    }

    private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
        final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
        return new TypeAdapter<C>() {
            @Override public void write(JsonWriter out, C value) throws IOException
            {
                JsonElement tree = delegate.toJsonTree(value);
                beforeWrite(value, tree);
                elementAdapter.write(out, tree);
            }
            @Override public C read(JsonReader in) throws IOException {
                JsonElement tree = elementAdapter.read(in);
                afterRead(tree);
                return delegate.fromJsonTree(tree);
            }
        };
    }

    /**
     * Override this to muck with {@code toSerialize} before it is written to
     * the outgoing JSON stream.
     */
    protected void beforeWrite(C source, JsonElement toSerialize) {
    }

    /**
     * Override this to muck with {@code deserialized} before it parsed into
     * the application type.
     */
    protected void afterRead(JsonElement deserialized) {
    }
}

Dan kemudian buat subclass untuk semua kelas yang perlu diperhitungkan. Anda harus membuat satu untuk setiap kelas yang berisi long (dalam hal ini). Tetapi Anda tidak perlu membuat serial apa pun kecuali nilai panjang (dan nilai spesifik bson lainnya)

public class MyTestObjectTypeAdapterFactory extends CustomizedTypeAdapterFactory<MyTestObject>
{
    public MyTestObjectTypeAdapterFactory()
    {
        super(MyTestObject.class);
    }

    @Override
    protected void beforeWrite(MyTestObject source, JsonElement toSerialize)
    {
        //you could convert back the other way here, I let mongo's document parser take care of that.
    }

    @Override
    protected void afterRead(JsonElement deserialized)
    {
        JsonObject timestamp = deserialized.getAsJsonObject().get("timestamp").getAsJsonObject();
        deserialized.getAsJsonObject().remove("timestamp");
        deserialized.getAsJsonObject().add("timestamp",timestamp.get("$numberLong"));
    }
}

lalu buat Gson dengan:

Gson gson = new GsonBuilder().registerTypeAdapterFactory(new MyTestObjectTypeAdapterFactory()).create();



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Meteor - collection.find() selalu mengembalikan semua bidang

  2. Bagaimana Anda bisa menentukan urutan properti dalam objek javascript untuk indeks MongoDB di node.js?

  3. Ubah nilai variabel dalam dokumen setelah beberapa waktu berlalu?

  4. Konversikan kondisi pembuat kueri ke operasi MongoDB termasuk larik subdokumen bersarang

  5. Mengapa Spring ReactiveMongoRepository tidak memiliki metode penyimpanan untuk Mono?