Spring Data Jpa 配合MongoDB实现持久层对象属性动态增加


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;

}
@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存储结果:


第一次单元测试,存储的数据没有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存储数据的特性所决定的。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值