MongoDB中_class欄位的作用
阿新 • • 發佈:2018-12-21
我們知道,如果你用Java的Sping Data 框架對映Pojo為MongoDB資料時,資料庫中會自動給你新增一個_class欄位,那這個欄位是幹嘛用的呢?我們可以不可以不要這個欄位呢?
直接上結論:答案其實很簡答,這個欄位就是用來對映Pojo的,更具體的說,是為了方便處理Pojo中存在繼承的情況,增加系統的擴充套件性的,接下來上例子:
_class欄位幫助對映子類
為了方便演示,這裡用Spring Data 給我們提供的mongoTemplate來操作。有關mongoDB和Spring Data的環境我就不貼了,直接上測試程式碼:
擁有繼承關係的實體類
@Document是把一個java類宣告為mongodb的文件,可以通過collection引數指定這個類對應的文件。
父類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; } }
子類 Student
@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層
Dao介面
public interface PersonDao {
void addPerson(Person person);
Person findPersonByName(String name);
}
Dao實現
@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條資料:
查詢小張,得到的類是Student類嗎?
可以看到,最終展示的是Student的詳細資訊,說明_class能幫助我們反序列化出子類。
那如果去掉了_class列,會是什麼樣呢?
去掉_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類。