类型映射
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 Data MongoDB 将类型信息存储为实际根类的最后一个字段以及嵌套类型(因为它很复杂并且是 Contact
的子类型)。因此,如果您现在使用 mongoTemplate.findAll(Object.class, "sample")
,您可以发现存储的文档是 Sample
实例。您还可以发现 value 属性实际上是 Person
。
自定义类型映射
如果您想避免将整个 Java 类名作为类型信息写入,而是希望使用一个键,您可以在实体类上使用 @TypeAlias
注解。如果您需要进一步自定义映射,请查看 TypeInformationMapper
接口。可以将该接口的实例配置在 DefaultMongoTypeMapper
上,而 DefaultMongoTypeMapper
又可以配置在 MappingMongoConverter
上。以下示例展示了如何为实体定义类型别名
@TypeAlias("pers")
class Person {
}
请注意,生成的文档在_class
字段中包含pers
作为值。
类型别名仅在映射上下文了解实际类型时才有效。所需的实体元数据是在第一次保存时确定的,或者必须通过配置的初始实体集提供。默认情况下,配置类会扫描基本包以查找潜在的候选者。
|
配置自定义类型映射
以下示例展示了如何在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
。