【问题标题】:Manual references support手动参考支持
【发布时间】:2013-02-18 15:12:50
【问题描述】:

考虑类:

class Person {
    String name;
    Person father;
    Person mother;
    List<Person> children;
}

有没有办法向 jongo 表明 fathermotherchildren 对于同一集合中的其他对象而不是嵌入对象应该是 manual references

注意:这与DBRefs 不同。

【问题讨论】:

    标签: java mongodb jongo


    【解决方案1】:

    还没有。

    最简单的方法是手动发出第二个查询。

    尽管如此,您可以适当地创建一个 Jackson 反序列化器以在解组过程中获取文档。 几个月前,我们在 unmarhsalling 期间创建了一个获取 DBRef 的峰值,此代码可以提供帮助:Handle DBRef during (un)marshalling

    欢迎添加feature request

    【讨论】:

      【解决方案2】:

      我用一种方法来处理它。不确定它是否完美,但它适用于我自己。

      假设你有这些类

      public class MyObject {
      
          @Id
          private String id;
          private MyEmbeddedObject embeddedObject;
      
          public String getId() {
              return this.id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
          public MyEmbeddedObject getEmbeddedObject() {
              return this.embeddedObject;
          }
      
          public void setEmbeddedObject(MyEmbeddedObject embeddedObject) {
              this.embeddedObject = embeddedObject;
          }
      
      }
      
      
      public class MyEmbeddedObject {
      
          @Id
          private String id;
      
          public String getId() {
              return this.id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
      }
      

      您希望将 MyEmbeddedObject 存储在集合“embed”中,并将 Object 存储在集合“object”中,并手动引用“embed”集合 ID。例如:

      object : { id:1, embeddedObjectId: 99 }
      embed : { id : 99 }
      

      您可以为 MyEmbeddedObject 实现自定义序列化器和反序列化器

      public class MyEmbeddedObjectSerializer extends JsonSerializer<MyEmbeddedObject> {
      
          @Override
          public void serialize(MyEmbeddedObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
              jgen.writeText(value.getId());
          }
      }
      
      public class MyEmbeddedObjectDeserializer extends JsonDeserializer<MyEmbeddedObject> {
      
          @Override
          public MyEmbeddedObject deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
              MyEmbeddedObject obj = new MyEmbeddedObject();
              obj.setId(jsonParser.getString());
              return new MyEmbeddedObject();
      
          }
       }
      

      如果您在 Jongo 中注册您的序列化程序,问题是它将作为 MyObject 的成员用于 MyEmbeddedObject,但当它自己存储在“嵌入”集合中时也用于 MyEmbeddedObject。

      为了仅在 MyEmbeddedObject 嵌入 MyOBject 时应用自定义序列化器/反序列化器,我使用 Mixin 注释。

      public interface MyObjectMixIn {
      
          @JsonSerialize(using=MyEmbeddedObjectSerializer .class)
          public MyEmbeddedObject getEmbeddedObject();
      
          @JsonDeserialize(using=MyEmbeddedObjectDeserializer.class)
          public void setEmbeddedObject(MyEmbeddedObject embeddedObject);
      
      }
      

      然后定义一个模块

      public class MyModule extends SimpleModule {
          @Override
          public void setupModule(SetupContext context) {
              context.setMixInAnnotations(MyObject.class, MyObjectMixIn.class);
          }
      }
      

      最后在 Jongo 中注册模块

      Jongo jongo = new Jongo(db, JacksonMapper.Builder().registerModule(new MyModule ()).build());
      

      现在在 Mongo 中使用它来存储

      1. 将 embeddedObject 本身存储在集合“embed”中以获取 id
      2. 确保object的embeddedObject成员包含id
      3. 将对象存储在集合“object”中。只会存储嵌入对象的 id

      读取数据存储

      1. 从集合“object”中读取对象。嵌入对象将仅使用其 ID 进行初始化
      2. 如果需要,请阅读“embed”集合中的 embeddedObject。

      编辑:为了避免延迟加载并在反序列化时加载完整的对象,来自 Jackson 的 HandlerInstantiator 对象对于自定义序列化器和反序列化器构造机制很有用。

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-24
        相关资源
        最近更新 更多