Spring Data Jpa 配合MongoDB實現持久層物件屬性動態增加
阿新 • • 發佈:2018-12-24
MongoDB作為NOSQL資料庫,基於文件儲存這一特性,使得儲存物件沒有像關係型資料庫有著約束。例如,當我們使用MySQL作為資料庫,當我們想要增加持久層Entity屬性時(所增加的屬性,必須儲存在資料庫的情況,除非所增加的屬性,不做為儲存,只是持久層Entity臨時的屬性),不得不為這個Entity所對應的表,增加欄位,否則所增加的屬性無法儲存,如果使用ORM框架,在對映過程中,還會出現異常。而MongoDB,使用BSON作為資料儲存格式,使得其沒有像關係型資料庫這樣較強的約束,在使用過程,持久層Entity可以隨時動態增加屬性,而MongoDB無需做任何更改。以下是Demo演示:
Demo工程地址:
https://github.com/faryang-sh/SpringDataJPALearning.git
實體定義:
@AllArgsConstructor
@Data
@ToString
public class Student {
@Id
private Long id;
private String name;
private Integer age;
private School shool;
//第二次執行單元測試加的
// private String home;
}
Repository:@AllArgsConstructor @Data @Builder @ToString public class School { @Id private Long id; private String name; private String address; }
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屬性/** * 第一次單元測試 * - 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屬性 * @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儲存結果:
第一次單元測試,儲存的資料沒有home屬性,第二次單元測試前,為Student加上了home,使得儲存的資料具有home屬性,而在MongoDB層面,未做任何修改,說明,基於Spring Data JPA和MongoDB,可以實現Entity的動態增加。
在對儲存資料做查詢單元測試時,發現Entity屬性的增加亦或是缺失,對程式執行無影響。單元測試程式碼如下:
/**
* 對查詢結果列印
*
*/
@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屬性增加和屬性,對程式執行無影響,影響的只是返回資料是否會缺失。
通過以上測試,說明Spring Data JPA對應MongoDB支援,在Entity屬性上,沒有想關係型資料庫那樣,具有較強的約束,框架對其只是做了屬性資料的對映,沒有校驗其資料欄位和Entity屬性是否一一對應,而這正是MongoDB儲存資料的特性所決定的。