咱们知道,若是你用Java的Sping Data 框架映射Pojo为MongoDB数据时,数据库中会自动给你添加一个_class字段,那这个字段是干吗用的呢?咱们能够不能够不要这个字段呢?java
直接上结论:答案其实很简答,这个字段就是用来映射Pojo的,更具体的说,是为了方便处理Pojo中存在继承的状况,增长系统的扩展性的,接下来上例子:mongodb
为了方便演示,这里用Spring Data 给咱们提供的mongoTemplate来操做。有关mongoDB和Spring Data的环境我就不贴了,直接上测试代码:数据库
@Document是把一个java类声明为mongodb的文档,能够经过collection参数指定这个类对应的文档。app
父类Person框架
@Document(collection = "test") public class Person { protected String name; protected int age; //set/get方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
子类 Studentide
@Document(collection = "test") public class Student extends Person { String a; String b; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", a='" + a + '\'' + ", b='" + b + '\'' + '}'; } public String getA() { return this.a; } public void setA(String a) { this.a = a; } public String getB() { return this.b; } public void setB(String b) { this.b = b; } }
Dao接口测试
public interface PersonDao { void addPerson(Person person); Person findPersonByName(String name); }
Dao实现this
@Repository public class PersonDapImpl implements PersonDao { @Autowired MongoTemplate mongoTemplate; @Override public void addPerson(Person person) { mongoTemplate.save(person); } @Override public Person findPersonByName(String name) { Query query = new Query(Criteria.where("name").is(name)); Person person = mongoTemplate.findOne(query, Person.class); return person; } }
public class PersonDapImplTest extends BaseTest { @Autowired PersonDao personDao; @Test public void addPerson() { Person person = new Person(); person.setName("张"); person.setAge(10); personDao.addPerson(person); } @Test public void addStudent() { Student student = new Student(); student.setName("小张"); student.setAge(12); student.setA("a"); student.setB("b"); personDao.addPerson(student); } @Test public void findPerson() { System.out.println("==============开始查找=============="); Person person = personDao.findPersonByName("小张"); System.out.println(); System.out.println(); System.out.println(); if (person != null) { System.out.println(person.toString()); }else { System.out.println("null"); } } }
测试中,小张是张的子类,mongoDB中已经插入了2条数据:code
查询小张,获得的类是Student类吗?blog
那若是去掉了_class列,会是什么样呢?
去掉_class的方法须要配置一下
须要配置MappingConverter:更详细的去掉_class的方法能够参考其余博文。
@Bean public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory, CustomConversions conversions) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context); // remove _class field // mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); mappingConverter.setCustomConversions(conversions); return mappingConverter; }
去掉_class后:
再次查询"小张"
能够看到,mongoDB没法帮助咱们来映射子类了。返回的数据被反序列化成了Person类。