1、表的关系:
分别有三个表:课程表、学生表、分数表。课程和学生的关系是多对多的,因为一个学生对应多个课程,而一个课程被多个学生选修。如果用一对多、多对一的观点来看待课程和学生的关系显然是不对的,因为课程表和学生表中都没有外键。
因此,为了找到表之间多对多的关系,需要引入第三个表(分数表),分数表中含有课程表和学生表的主键,可以将两个本来没有关联的表通过第三个表连接起来。
2、实体关系表达:
学生:
public class Student {
private Integer studentno;
private String sname;
private String sex;
private String birthday;
private String classno;
private Float point;
private String phone;
private String email;
private Set<Course> courses=new HashSet<Course>();
public Integer getStudentno() {
return studentno;
}
public void setStudentno(Integer studentno) {
this.studentno = studentno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getClassno() {
return classno;
}
public void setClassno(String classno) {
this.classno = classno;
}
public Float getPoint() {
return point;
}
public void setPoint(Float point) {
this.point = point;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
@Override
public String toString() {
return "Student{" +
"studentno=" + studentno +
", sname='" + sname + '\'' +
", sex='" + sex + '\'' +
", birthday='" + birthday + '\'' +
", classno='" + classno + '\'' +
", point=" + point +
", phone='" + phone + '\'' +
", email='" + email + '\'' +
", courses=" + courses +
'}';
}
}
课程:
public class Course {
private Integer courseid;
private double credit;
private String courseno;
private String cname;
private String type;
private Integer period;
private Set<Student> students=new HashSet<Student>();
public Integer getCourseid() {
return courseid;
}
public void setCourseid(Integer courseid) {
this.courseid = courseid;
}
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
public String getCourseno() {
return courseno;
}
public void setCourseno(String courseno) {
this.courseno = courseno;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getPeriod() {
return period;
}
public void setPeriod(Integer period) {
this.period = period;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Course{" +
"courseid=" + courseid +
", credit=" + credit +
", courseno='" + courseno + '\'' +
", cname='" + cname + '\'' +
", type='" + type + '\'' +
", period=" + period +
", students=" + students +
'}';
}
}
两个实体中,分别创建了两个set集合存储对方实体对象。
3、多对多的配置:
(1)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 package="pers.zhb.domain">
<class name="Student" table="student">
<id name="studentno" column="studentno" >
<generator class="native"></generator>
</id>
<property name="birthday" column="birthday"></property>
<property name="classno" column="classno"></property>
<property name="email" column="email"></property>
<property name="phone" column="phone"></property>
<property name="sex" column="sex"></property>
<property name="sname" column="sname"></property>
<property name="point" column="point"></property>
<set name="courses" table="score" inverse="true">
<key column="studentno"></key>
<many-to-many class="Course" column="courseid"></many-to-many>
</set>
</class>
</hibernate-mapping>
前面的内容大多是对主键和普通属性的配置,主要是对于一对多关系的配置:
<set name="courses" table="score" inverse=“true”>
<key column="studentno"></key>
<many-to-many class="Course" column="courseid"></many-to-many>
</set>
name属性:对应的多的一方的集合名字。
table:联系student表和course表关系的第三个表。
column:student表的外键。
class:对应的多的一方(课程)的类名。
column:对应的多的一方的类的主键。
inverse:等于true相当于让学生一方放弃维护关系,因为双方同时维护关系会导致错误。
(2)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 package="pers.zhb.domain">
<class name="Course" table="course">
<id name="courseid" column="courseid" >
<generator class="native"></generator>
</id>
<property name="courseno" column="courseno"></property>
<property name="cname" column="cname"></property>
<property name="credit" column="credit"></property>
<property name="type" column="type"></property>
<property name="period" column="period"></property>
<set name="students" table="score">
<key column="courseid"></key>
<many-to-many class="Student" column="studentno"></many-to-many>
</set>
</class>
</hibernate-mapping>
(3)虽然联系student表和course表需要第三个表score,但是并不需要对score表进行配置。
4、多对多的基本操作:
(1)学生和课程的多对多添加:
public static void testadd() {
Session session = HibernateUtils.openSession();//获得session
Transaction transaction = session.beginTransaction();//开启事务
Student student=new Student();
student.setSname("翟");
student.setPoint(123f);
student.setClassno(46);
student.setSex("男");
student.setBirthday("2019-11-11");
student.setPhone("18739496522");
student.setEmail("34288334@qq.com");
Student student1=new Student();
student1.setSname("翟hb");
student1.setPoint(666f);
student1.setClassno(46);
student1.setSex("女");
student1.setBirthday("2019-11-11");
student1.setPhone("18739496522");
student1.setEmail("34288334@qq.com");
Course course=new Course();
course.setCourseno("123");
course.setCname("算法设计");
course.setType("必修");
course.setCredit(4);
course.setPeriod(22);
Course course1=new Course();
course.setCourseno("456");
course1.setCname("网络");
course1.setCredit(2);
course1.setPeriod(12);
course1.setType("必修");
student.getCourses().add(course);
student.getCourses().add(course1);
student1.getCourses().add(course);
student1.getCourses().add(course1);
session.save(student);
session.save(student1);
session.save(course);
session.save(course1);
transaction.commit();//提交事务
session.close();//关闭资源
}
分别创建了两个学生对象和两个课程对象,在学生类的集合中添加两个课程对象,同样,在课程类的集合中添加两个学生对象,并将他们转换为持久化状态。
运行结果:
学生:
课程:
分数:
(2)为一个学生添加课程:
public static void testadd1(){
Session session = HibernateUtils.openSession();//获得session
Transaction transaction = session.beginTransaction();//开启事务
Student student=session.get(Student.class,1);//获得要添加的学生对象
Course course=new Course();//创建课程对象
course.setCname("算法设计");
course.setType("必修");
course.setCredit(4);
course.setPeriod(22);
course.setCourseno("123");
student.getCourses().add(course);
session.save(course);//转化为持久态
transaction.commit();//提交事务
session.close();//关闭资源
}
运行结果:
学生:
课程:
分数:
可以看到学号为1的学生增加了课程id为1的课程。
(2)删除操作:
public static void testDel(){
Session session = HibernateUtils.openSession();//获得session
Transaction transaction = session.beginTransaction();//开启事务
Student student=session.get(Student.class,1);//获得要添加的学生对象
Course course=session.get(Course.class,1);
Course course1=session.get(Course.class,2);
student.getCourses().remove(course);
student.getCourses().remove(course1);
transaction.commit();//提交事务
session.close();//关闭资源
}
5、级联操作:
(1)级联保存:
public static void testadd1(){
Session session = HibernateUtils.openSession();//获得session
Transaction transaction = session.beginTransaction();//开启事务
Student student=session.get(Student.class,1);//获得要添加的学生对象
Course course=new Course();//创建课程对象
course.setCname("算法设计");
course.setType("必修");
course.setCredit(4);
course.setPeriod(22);
course.setCourseno("123");
student.getCourses().add(course);
transaction.commit();//提交事务
session.close();//关闭资源
}
<?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 package="pers.zhb.domain">
<class name="Course" table="course">
<id name="courseid" column="courseid" >
<generator class="native"></generator>
</id>
<property name="courseno" column="courseno"></property>
<property name="cname" column="cname"></property>
<property name="credit" column="credit"></property>
<property name="type" column="type"></property>
<property name="period" column="period"></property>
<set name="students" table="score" cascade="save-update"><!--一对多关系配置-->
<key column="courseid"></key><!--指定了集合表的外键-->
<many-to-many class="Student" column="studentno"></many-to-many>
</set>
</class>
</hibernate-mapping>
与一对多、多对一相似,级联操作的运用可以减少代码量。
(2)级联删除:
可以使用,但是危险系数较高。