public interface StudentRepository extends MongoRepository<Student, Long> {
Student findByName(String name);
}
MongoDB作爲NOSQL數據庫,基於文檔存儲這一特性,使得存儲對象沒有像關係型數據庫有着約束。例如,當我們使用MySQL作爲數據庫,當我們想要增加持久層Entity屬性時(所增加的屬性,必須存儲在數據庫的情況,除非所增加的屬性,不做爲存儲,只是持久層Entity臨時的屬性),不得不爲這個Entity所對應的表,增加字段,否則所增加的屬性無法存儲,如果使用ORM框架,在映射過程中,還會出現異常。而MongoDB,使用BSON作爲數據存儲格式,使得其沒有像關係型數據庫這樣較強的約束,在使用過程,持久層Entity可以隨時動態增加屬性,而MongoDB無需做任何更改。以下是Demo演示:
實體定義:
@AllArgsConstructor
@Data
@ToString
public class Student {
@Id
private Long id;
private String name;
private Integer age;
private School shool;
//第二次執行單元測試加的
// private String home;
}
@AllArgsConstructor
@Data
@Builder
@ToString
public class School {
@Id
private Long id;
private String name;
private String address;
}
Repository:
public interface SchoolReponsitory extends MongoRepository<School,Long> {
School findSchoolByName(String name);
}
public interface StudentRepository extends MongoRepository<Student, Long> {
Student findByName(String name);
}
單元測試:
第一次單元測試,Student沒有home屬性
/**
* 第一次單元測試
* - student實體沒有加home屬性
*
* @throws Exception
*/
@Test
public void insertStudentWithoutHome() throws Exception {
School school1 = schoolReponsitory.findSchoolByName("南京路中學");
School school2 = schoolReponsitory.findSchoolByName("北京路中學");
studentRepository.save(new Student(1L, "小明", 30,school1));
studentRepository.save(new Student(2L, "小紅", 40,school1));
studentRepository.save(new Student(3L, "小王", 50,school2));
}
第二次單元測試,Student有home屬性
/**
* 第二次單元測試
* - student實體加home屬性
* @throws Exception
*/
@Test
public void insertStudentWitHome() throws Exception {
School school1 = schoolReponsitory.findSchoolByName("南京路中學");
School school2 = schoolReponsitory.findSchoolByName("北京路中學");
studentRepository.save(new Student(4L, "tom", 30,school1,"1小區"));
studentRepository.save(new Student(5L, "peter", 40,school1,"2小區"));
studentRepository.save(new Student(6L, "joy", 50,school2,"3小區"));
}
結果:
第一次單元測試,MongoDB存儲結果:
第二次單元測試MongoDB存儲結果:
從mongodb存儲結果發現:
第二次單元測試時,爲Student加上了home屬性,但是第一次存儲的數據,並沒有加上home屬性,而且對mongodb沒有做任何更改操作。
在對上面存儲的數據,進行查詢時,對Student中home屬性,增加亦或是刪除,對程序正常進行沒有影響,以下是查詢的單元測試代碼:
@Test
public void findAll(){
List<Student> students = studentRepository.findAll();
students.forEach(student -> {
System.out.println(student);
});
}
Student中沒有home屬性時,打印結果如下:
Student(id=1, name=小明, age=30, shool=School(id=1, name=南京路中學, address=南京路))
Student(id=2, name=小紅, age=40, shool=School(id=1, name=南京路中學, address=南京路))
Student(id=3, name=小王, age=50, shool=School(id=2, name=北京路中學, address=北京路))
Student(id=4, name=tom, age=30, shool=School(id=1, name=南京路中學, address=南京路))
Student(id=5, name=peter, age=40, shool=School(id=1, name=南京路中學, address=南京路))
Student(id=6, name=joy, age=50, shool=School(id=2, name=北京路中學, address=北京路))
Student有home屬性時,打印結果如下:
Student(id=1, name=小明, age=30, shool=School(id=1, name=南京路中學, address=南京路), home=null)
Student(id=2, name=小紅, age=40, shool=School(id=1, name=南京路中學, address=南京路), home=null)
Student(id=3, name=小王, age=50, shool=School(id=2, name=北京路中學, address=北京路), home=null)
Student(id=4, name=tom, age=30, shool=School(id=1, name=南京路中學, address=南京路), home=1小區)
Student(id=5, name=peter, age=40, shool=School(id=1, name=南京路中學, address=南京路), home=2小區)
Student(id=6, name=joy, age=50, shool=School(id=2, name=北京路中學, address=北京路), home=3小區)
上面這兩個測試說明,說明在持久層Entity屬性的增加和刪除,MongoDB無需做任何修改情況下,程序依然能夠正常執行。