MongoDB中的"_class"字段是由Spring Data MongoDB自动添加的,用于存储每个文档所属的Java类的全限定名。这个字段的存在是为了在查询时能够准确地将文档映射回Java对象。
但在某些情况下,我们可能不希望自动添加"_class"字段。例如,当我们使用MongoDB作为纯粹的文档存储时,不需要将文档映射回Java对象,或者当我们希望减少存储空间和网络传输时。
下面是一种方法可以在Spring Data MongoDB中禁用自动添加"_class"字段。
首先,我们需要定义一个自定义的MappingMongoConverter并覆盖其getMappingContext()方法。MappingMongoConverter是Spring Data MongoDB中负责对象与文档之间的转换的类。
public class CustomMappingMongoConverter extends MappingMongoConverter {
public CustomMappingMongoConverter(MongoDbFactory mongoDbFactory, MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
super(mongoDbFactory, mappingContext);
}
@Override
protected void writeInternal(Object obj, Document dbo, MongoPersistentEntity<?> entity) {
super.writeInternal(obj, dbo, entity);
dbo.remove("_class");
}
@Override
protected void writeInternal(Object obj, Bson bson) {
super.writeInternal(obj, bson);
((BsonDocument) bson).remove("_class");
}
}
上面的代码中,我们通过覆盖writeInternal()方法,在将Java对象转换为文档或Bson时删除"_class"字段。
接下来,我们需要修改MongoConfiguration类,让它返回我们自定义的MappingMongoConverter。
@Configuration
public class MongoConfiguration extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "myDB";
}
@Override
public MongoClient mongoClient() {
return MongoClients.create("mongodb://localhost:27017");
}
@Override
public MongoCustomConversions customConversions() {
return new MongoCustomConversions(Collections.emptyList());
}
@Override
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter converter = new CustomMappingMongoConverter(mongoDbFactory(),
mappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return converter;
}
}
在上面的配置类中,我们返回了自定义的MappingMongoConverter,并且将默认的TypeMapper设置为null,这样就完全禁用了"_class"字段的自动添加。
最后,我们可以编写一个简单的应用程序来测试是否成功禁用了"_class"字段。
@Repository
public class MyRepository {
@Autowired
private MongoTemplate mongoTemplate;
public void saveDocument(Document document) {
mongoTemplate.save(document);
}
public Document findDocumentById(String id) {
return mongoTemplate.findById(id, Document.class);
}
}
@Service
public class MyService {
@Autowired
private MyRepository myRepository;
public void saveDocument(Document document) {
myRepository.saveDocument(document);
}
public Document findDocumentById(String id) {
return myRepository.findDocumentById(id);
}
}
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
在上面的代码中,我们定义了一个MyRepository和MyService类,用于保存和查找MongoDB中的文档。注意到这里的Document类没有任何与"_class"字段相关的注解。
然后,我们可以编写一个测试类来验证自动添加"_class"字段是否成功禁用。
@SpringBootTest
@RunWith(SpringRunner.class)
public class MyServiceTest {
@Autowired
private MyService myService;
@Test
public void testSaveAndFindDocument() {
Document document = new Document("name", "John Doe");
myService.saveDocument(document);
Document savedDocument = myService.findDocumentById(document.getId());
System.out.println(savedDocument.toJson());
}
}
在上面的测试方法中,我们保存了一个简单的文档,并从数据库中检索出该文档。如果成功禁用了"_class"字段,输出的文档应该不包含"_class"字段。
通过运行上述测试,我们可以确认"_class"字段已成功禁用。
综上所述,我们可以通过自定义MappingMongoConverter并覆盖writeInternal()方法,以及修改MongoConfiguration类来禁用Spring Data MongoDB自动添加的"_class"字段。这样可以在某些情况下减少存储空间和网络传输。