咱們知道,若是你用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類。