Hibernate上路_14-多对多表单操作

多对多关联中没有父子关系。但可以按照日常思维,把学生看做主对象,把课程看做从对象。
示例:学生可以选多门课程,每门课程亦可被多名学生选择。

1.POJO.hbm.xml配置:

1)学生配置:

<hibernate-mapping package="cn.cvu.hibernate.domain">
	<class name="PojoStudent" table="tb_student" select-before-update="true">
		<id name="id" column="t_id" type="int">
			<generator class="native" />
		</id>
		<property name="name" column="t_name" />
		
		<!-- 多对多关系配置
			set:本类中关联的对方类集合类型
			name=本类中关联的对方类集合属性名。课程属性
			table=两表关联生成的中间表,和对方的配置相同       -->
		<set name="courses" table="tb_student_course">
		
			<!-- column="本表主键在中间表中的外键"         整个set配置中,这里是配置关于学生自己的 -->
			<key column="t_student_id"></key>  
			
			<!-- 多对多关联
				class="<set>的对方name对应的POJO类" 
				column="对方类在中间表中的外键"           -->
			<many-to-many  
				class="cn.cvu.hibernate.domain.PojoCourse" 
				column="t_course_id"/>
		</set>
	</class>
</hibernate-mapping>

2)课程配置:

<hibernate-mapping package="cn.cvu.hibernate.domain">
	<class name="PojoCourse" table="tb_course" select-before-update="true">
		<id name="id" column="t_id" type="int">
			<generator class="native"/>
		</id>
		<property name="name" column="t_name"/>
		
		<!-- 多对多关系配置
			set:本类中关联的对方类集合类型
			name=本类中关联的对方类集合属性名。学生属性
			table=两表关联生成的中间表,和对方的配置相同  -->
		<set name="students" table="tb_student_course">
		
			<!-- column="本表主键在中间表中的外键"          整个set配置中,这里是配置关于课程自己的 -->
			<key column="t_course_id"></key>
			
			<!-- 多对多关联
				class="<set>的对方name对应的POJO类" 
				column="对方类在中间表中的外键"           -->
			<many-to-many  
				class="cn.cvu.hibernate.domain.PojoStudent" 
				column="t_student_id"/>
		</set>
	</class>
</hibernate-mapping>


2.插入数据测试:

1)代码:

public void insert() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();

		//创建学生
		PojoStudent student = new PojoStudent();
		student.setName("Eminem");
		
		//创建课程
		PojoCourse course = new PojoCourse();
		course.setName("英语");
		
		//配置关联
		student.getCourses().add(course);
		course.getStudents().add(student);
		
		//保存全部相关数据
		session.save(student);
		session.save(course);
		
		transaction.commit();
		session.close();
	}


2ConstraintViolationException报错:

org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'PRIMARY'   

3)解决主键冲突:

对于双向n-n关联须把其中一端的inverse设置为true,否则可能会造成主键冲突。

  

结果:

Hibernate上路_14-多对多表单操作

4)代码:

public void insert() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();

		//创建学生
		PojoStudent student = new PojoStudent();
		student.setName("JAY-Z");
		
		//使用已有课程
		PojoCourse course = (PojoCourse) session.get(PojoCourse.class, 2);
		
		//配置关联
		student.getCourses().add(course);
		course.getStudents().add(student);
		
		//保存全部相关数据
		session.save(student);
		session.save(course);
		
		transaction.commit();
		session.close();
	}

Hibernate上路_14-多对多表单操作

3.多对多常见操作-保存:

1)双方都未inverse=true放弃修改关联的能力:

2)插入操作:


4.多对多常见操作-解除关系:

1)代码:

public void delete() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();

		//提取已有学生
		PojoStudent student = (PojoStudent) session.get(PojoStudent.class, 2);
		//提取已有课程
		PojoCourse course = (PojoCourse) session.get(PojoCourse.class, 2);		

		//学生取消课程,即在中间表删除关联记录。
  //在都没有inverse=true时,一方操作即可。设置了inverse=true的一方修改无效
		student.getCourses().remove(course);
		
		transaction.commit();
		session.close();
	}


2)结果:

Hibernate上路_14-多对多表单操作 

5.多对多常见操作-删除一方:

删除一个有选课的学生,将自动删除中间表里其所选科目记录。

1)代码:

public void delete() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();

		//脱管对象
		PojoStudent student = new PojoStudent();
		student.setId(3);
		
		//删除脱管对象,从表单删除此学生
		session.delete(student);
		
		transaction.commit();
		session.close();
	}


2)结果:

Hibernate上路_14-多对多表单操作 

注意:不建议多对多关系表建立级联!否则删除一方持久化对象,一系列连锁数据将全都被清除!删除脱管对象时cascade 无效

- end
 

你可能感兴趣的:(sql,Hibernate,jdbc,多对多,数据持久化)