有哪些方法可以使用针对性能优化的MongoTemplate?

时间:2014-03-30 09:48:32

标签: spring-data spring-data-mongodb

我注意到使用MongoTemplate.insert(Collection<?> …)方法的批量插入比使用MongoDB Java驱动程序慢得多。

据我了解,差异来自于MongoTemplate正在执行一些串行操作,而我正在讨论下一行代码:

for (T o : batchToSave) {

  initializeVersionProperty(o);
  BasicDBObject dbDoc = new BasicDBObject();

  maybeEmitEvent(new BeforeConvertEvent<T>(o));
  writer.write(o, dbDoc);

  maybeEmitEvent(new BeforeSaveEvent<T>(o, dbDoc));
  dbObjectList.add(dbDoc);
}

并且:

for (T obj : batchToSave) {
  if (i < ids.size()) {
    populateIdIfNecessary(obj, ids.get(i));
    maybeEmitEvent(new AfterSaveEvent<T>(obj, dbObjectList.get(i)));
  }
  i++;
}

现在,有没有办法将MongoTemplate配置为无效繁重的操作,可能不会发布事件或什么?

1 个答案:

答案 0 :(得分:3)

所以,首先问题是:你得到的是什么?你得到:

  • 乐观锁定
  • 对象到文档的映射
  • 持久性事件
  • 资源管理
  • 例外翻译

因此,如果你问是否有可能免费获得所有这些,答案显然是:不。但通常情况下,文档转换的对象需要花费最多的时间,因此有几个选项可以调整过程:

实施自定义转换器

将复杂的域对象移交给模板 - 根据定义 - 要求将其转换为DBObject。您可以通过实现Converter<YourType, DBObject>并注册它来快捷方式(有关详细信息,请参阅reference documentation)。这将导致跳过基于反射的转换机制并调用转换器。这将使您仍然可以从乐观锁定和事件中受益。

首先保留DBObject

更有效的方法是首先将DBObject传递给模板(即手动转换对象并在模板外部进行转换)。这当然会阻止事件和乐观锁定机制有用。

使用回调方法

如果您真的要跳过所有映射和事件功能,请使用MongoTemplate上的回调方法直接与驱动程序API进行交互:

public void someMethod(final List<YourObject> objects) {

  template.execute("someCollection", new CollectionCallback<Void>() {
    public Void doInCollection(DBCollection collection) {
      // you code interacting with the collection
    }
  }
}

这将使您获得资源管理的最后好处,并将MongoDB异常异常转换为Spring的DataAccessException层次结构。