Spring Data 配合MongoDB實現持久層對象屬性動態增加

 

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無需做任何修改情況下,程序依然能夠正常執行。


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章