Hibernate基础知识(5)

本文介绍Hibernate框架中多对多关联关系的映射配置方法,并通过学生选课案例演示了多对多关联的保存、修改及删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、多对多关联关系映射

      以 学生Student选课Course为例。

1、实体类编写和多对多配置映射配置

学生类:

package lsq.hibernate.manytomany;

import java.util.HashSet;
import java.util.Set;

//学生类
public class Student {
	private Integer id;
	private String sname;
	private Set<Course> courses = new HashSet<Course>();

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public Set<Course> getCourses() {
		return courses;
	}

	public void setCourses(Set<Course> courses) {
		this.courses = courses;
	}

}

课程类:

package lsq.hibernate.manytomany;

import java.util.HashSet;
import java.util.Set;

//课程类
public class Course {
	private Integer id;
	private String cname;
	private Set<Student> students = new HashSet<Student>();

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getCname() {
		return cname;
	}

	public void setCname(String cname) {
		this.cname = cname;
	}

	public Set<Student> getStudents() {
		return students;
	}

	public void setStudents(Set<Student> students) {
		this.students = students;
	}

}
Student.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="lsq.hibernate.manytomany.Student" table="students" catalog="hibernate3day2">
			<id name="id">
				<generator class="identity"></generator>
			</id>
			<property name="sname"></property>
			<!-- 多对多 -->
			<!-- 
				name:关联属性名
				table:产生中间表表名
			 -->
			 <set name="courses" table="student_course">
			 	<!-- 当前对象在中间表产生外键列名 -->
			 	<key column="student_id"></key>
			 	<!-- column指定集合对应表在中间表产生外键列名 -->
			 	<many-to-many column="course_id" class="lsq.hibernate.manytomany.Course"></many-to-many>
			 </set>
	</class>
</hibernate-mapping>
Course.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="lsq.hibernate.manytomany.Course" table="courses" catalog="hibernate3day2">
			<id name="id">
				<generator class="identity"></generator>
			</id>
			<property name="cname"></property>
			<!-- 多对多配置 -->
			<set name="students" table="student_course" inverse="true">
				<!-- 当前对象外键列 -->
				<key column="course_id"></key>
				<many-to-many column="student_id" class="lsq.hibernate.manytomany.Student"></many-to-many>
			</set>
	</class>
</hibernate-mapping>

案例一、测试保存

      多对多关联映射中,不存在一对多那样父子表关系。

      在实际开发中,多对多可以不配置 cascade。

      * 只要两个对象,建立一次关系,就会向中间表插入一条数据。

      student1.getCourses().add(course1);  // 产生一条 insert
      course1.getStudents().add(student1); // 产生一条 insert 
      解决: 只需要建立一方面 关联,或者在任何一方 添加inverse=true  (推荐)。

package lsq.hibernate.manytomany;

import lsq.hibernate.utils.HibernateUtils;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

//多对多测试
public class HibernateTest {
	
	//测试保存
	@Test
	public void demo1(){
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		//保存学生
		Student student1 = new Student();
		student1.setSname("关羽");
		
		Student student2 = new Student();
		student2.setSname("张飞");
		
		session.save(student1);
		session.save(student2);
		
		//保存课程
		Course course1 = new Course();
		course1.setCname("语文");
		
		Course course2 = new Course();
		course2.setCname("数学");
		
		session.save(course1);
		session.save(course2);
		
		//关羽选修语文
		student1.getCourses().add(course1);
		//course1.getStudents().add(student1);
		
		transaction.commit();
		session.close();
	}
}


案例二、测试解除关系,删除中间表数据

	@Test
	public void demo2(){
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		Student student = (Student) session.get(Student.class, 1);
		Course course = (Course) session.get(Course.class, 1);
		
		//解除关系
		student.getCourses().remove(course);
		
		transaction.commit();
		session.close();
	}
案例三、改变学生选课关系

      student.getCourses().remove(course); 删除选课数据
      student.getCourses().add(course); 重新选课


案例四、学生存在选课记录,学生数据能否删除

      可以,先删除关羽所有选课记录,再删除关羽数据 
      * 如果删除课程,先删除选课记录,再删除课程

	@Test
	public void demo3(){
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		Student student = (Student) session.get(Student.class, 1);
		
		//删除学生
		session.delete(student);
		
		transaction.commit();
		session.close();
	}


案例五、删除课程时,能否将选课学生删除 (在实际中很少用)

      可以,使用 cascade 级联

      * 多对多 最好不要使用 级联操作

	// 删除课程,将选该课程的学生删除
	// 课程---> 学生 配置Course.hbm.xml
	// <set name="students" table="student_course" cascade="delete">
	@Test
	public void demo4() {
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();

		Course course = (Course) session.get(Course.class, 1);
		session.delete(course);

		transaction.commit();
		session.close();
	}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值