Type Mapping
Type Mapping
MongoDB 集合可以包含表示各种类型实例的文档。如果您存储一个类的层次结构或有一个类型为 Object
的属性的类,则此功能很有用。在后一种情况下,在检索该对象时必须正确读取该属性中保存的值。因此,我们需要一种机制来存储实际文档旁边的类型信息。
为了实现这一点,MappingMongoConverter
使用 MongoTypeMapper
抽象,其主要实现是 DefaultMongoTypeMapper
。其默认行为是将完全限定类名存储在文档中的 _class
下。类型提示是针对顶级文档以及针对每个值(如果它是一个复杂类型且是已声明的属性类型的子类型)编写的。以下示例(末尾带有 JSON 表示)显示了映射是如何工作的:
class Sample {
Contact value;
}
abstract class Contact { … }
class Person extends Contact { … }
Sample sample = new Sample();
sample.value = new Person();
mongoTemplate.save(sample);
{
"value" : { "_class" : "com.acme.Person" },
"_class" : "com.acme.Sample"
}
Spring 数据 MongoDB 将类型信息存储为实际根类的最后一个字段以及嵌套类型(因为它很复杂并且是 Contact
的子类型)。因此,如果您现在使用 mongoTemplate.findAll(Object.class, "sample")
,您可以发现存储的文档是 Sample
实例。您还可以发现值属性实际上是一个 Person
。
Customizing Type Mapping
如果您不想将整个 Java 类名写为类型信息,而是想使用键,则可以在实体类上使用 @TypeAlias
注释。如果您需要进一步自定义映射,请查看 TypeInformationMapper
接口。该接口的一个实例可以在 DefaultMongoTypeMapper
中配置,后者又可以在 MappingMongoConverter
中配置。以下示例说明如何定义实体的类型别名:
@TypeAlias("pers")
class Person {
}
请注意,生成的文档包含 _class
字段中的值 pers
。
只有映射上下文知道实际类型时,类型别名才起作用。所需的实体元数据是在第一次保存时确定的,或者必须通过配置的初始实体集提供。默认情况下,配置类会扫描基本包以查找潜在的候选对象。
@Configuration
class AppConfig extends AbstractMongoClientConfiguration {
@Override
protected Set<Class<?>> getInitialEntitySet() {
return Collections.singleton(Person.class);
}
// ...
}
Configuring Custom Type Mapping
以下示例展示如何在 MappingMongoConverter
中配置一个自定义 MongoTypeMapper
:
class CustomMongoTypeMapper extends DefaultMongoTypeMapper {
//implement custom type mapping here
}
MongoTypeMapper
@Configuration
class SampleMongoConfiguration extends AbstractMongoClientConfiguration {
@Override
protected String getDatabaseName() {
return "database";
}
@Bean
@Override
public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory databaseFactory,
MongoCustomConversions customConversions, MongoMappingContext mappingContext) {
MappingMongoConverter mmc = super.mappingMongoConverter();
mmc.setTypeMapper(customTypeMapper());
return mmc;
}
@Bean
public MongoTypeMapper customTypeMapper() {
return new CustomMongoTypeMapper();
}
}
<mongo:mapping-converter type-mapper-ref="customMongoTypeMapper"/>
<bean name="customMongoTypeMapper" class="com.acme.CustomMongoTypeMapper"/>
请注意,前面的示例扩展了 AbstractMongoClientConfiguration
类并覆盖了 MappingMongoConverter
的 bean 定义,其中我们配置了自定义的 MongoTypeMapper
。