此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data MongoDB 4.4.4spring-doc.cadn.net.cn

自定义转化

下面的 Spring 示例Converterimplementation 从String到自定义Emailvalue 对象:spring-doc.cadn.net.cn

@ReadingConverter
public class EmailReadConverter implements Converter<String, Email> {

  public Email convert(String source) {
    return Email.valueOf(source);
  }
}

如果您编写Converter其 source 和 target type 是 native 类型,我们无法确定我们应该将其视为 reading 还是 writing 转换器。 将转换器实例注册为两者可能会导致不需要的结果。 例如,Converter<String, Long>是模棱两可的,尽管尝试全部转换可能没有意义String实例转换为Long实例。 为了让您强制基础设施仅以一种方式注册转换器,我们提供了@ReadingConverter@WritingConverter在 converter implementation 中使用的 annotations。spring-doc.cadn.net.cn

转换器需要显式注册,因为不会从 Classpath 或容器扫描中选取实例,以避免向 conversion 服务进行不必要的注册以及此类注册产生的副作用。转换器注册为CustomConversions作为中央工具,允许根据源和目标类型注册和查询已注册的转换器。spring-doc.cadn.net.cn

CustomConversions附带一组预定义的转换器注册:spring-doc.cadn.net.cn

本地时间类型的默认转换器(例如LocalDateTimejava.util.Date) 依赖于系统默认时区设置在这些类型之间进行转换。您可以通过注册自己的转换器来覆盖默认转换器。

转换器消歧义

通常,我们会检查Converter它们转换的源类型和目标类型的实现。 根据其中之一是否是底层数据访问 API 可以本地处理的类型,我们将转换器实例注册为读取或写入转换器。 以下示例显示了 writing- 和 read 转换器(请注意,区别在于Converter):spring-doc.cadn.net.cn

// Write converter as only the target type is one that can be handled natively
class MyConverter implements Converter<Person, String> { … }

// Read converter as only the source type is one that can be handled natively
class MyConverter implements Converter<String, Person> { … }

基于类型的转换器

影响映射结果的最简单方法是通过@Field注解。 这允许使用非 MongoDB 类型,例如BigDecimal在域模型中,同时在 native 中保留值org.bson.types.Decimal128格式。spring-doc.cadn.net.cn

示例 1.显式目标类型映射
public class Payment {

  @Id String id; (1)

  @Field(targetType = FieldType.DECIMAL128) (2)
  BigDecimal value;

  Date date; (3)

}
{
  "_id"   : ObjectId("5ca4a34fa264a01503b36af8"), (1)
  "value" : NumberDecimal(2.099),                 (2)
  "date"  : ISODate("2019-04-03T12:11:01.870Z")   (3)
}
1 表示有效ObjectId将自动转换。看如何_idField 在 Mapping Layer 中处理了解详情。
2 所需的目标类型显式定义为Decimal128翻译过来就是NumberDecimal. 否则,BigDecimal值会被截取为String.
3 Date值由 MongoDB 驱动程序本身处理,并存储为ISODate.

上面的代码段对于提供简单的类型提示非常方便。要对映射过程进行更精细的控制,请执行以下作: 您可以使用MongoConverter实现,例如MappingMongoConverter.spring-doc.cadn.net.cn

MappingMongoConverter在尝试映射对象本身之前,检查是否有任何 Spring 转换器可以处理特定类。要“劫持”的MappingMongoConverter,也许是为了提高性能或其他自定义映射需求,您首先需要创建一个 Spring 的实现Converter接口,然后将其注册到MappingConverter.spring-doc.cadn.net.cn

有关 Spring 类型转换服务的更多信息,请参阅此处的参考文档。

写入转换器

以下示例显示了ConverterPersonobject 设置为org.bson.Document:spring-doc.cadn.net.cn

import org.springframework.core.convert.converter.Converter;

import org.bson.Document;

public class PersonWriteConverter implements Converter<Person, Document> {

  public Document convert(Person source) {
    Document document = new Document();
    document.put("_id", source.getId());
    document.put("name", source.getFirstName());
    document.put("age", source.getAge());
    return document;
  }
}

Reading Converter

The following example shows an implementation of a Converter that converts from a Document to a Person object:spring-doc.cadn.net.cn

public class PersonReadConverter implements Converter<Document, Person> {

  public Person convert(Document source) {
    Person p = new Person((ObjectId) source.get("_id"), (String) source.get("name"));
    p.setAge((Integer) source.get("age"));
    return p;
  }
}

Registering Converters

class MyMongoConfiguration extends AbstractMongoClientConfiguration {

	@Override
	public String getDatabaseName() {
		return "database";
	}

	@Override
	protected void configureConverters(MongoConverterConfigurationAdapter adapter) {
		adapter.registerConverter(new com.example.PersonReadConverter());
		adapter.registerConverter(new com.example.PersonWriteConverter());
	}
}

Big Number Format

MongoDB in its early days did not have support for large numeric values such as BigDecimal. To persist BigDecimal and BigInteger values, Spring Data MongoDB converted values their String representation. With MongoDB Server 3.4, org.bson.types.Decimal128 offers a native representation for BigDecimal and BigInteger. You can use the to the native representation by either annotating your properties with @Field(targetType=DECIMAL128) or by configuring the big decimal representation in MongoCustomConversions through MongoCustomConversions.create(config → config.bigDecimal(…)).spring-doc.cadn.net.cn