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)级联删除:

可以使用,但是危险系数较高。

Hibernate的多对多关系的更多相关文章

  1. 如何决解项目中hibernate中多对多关系中对象转换json死循环

    先写一下原因吧!我是写的SSH项目,在项目中我遇到的问题是把分页对象(也就是pageBean对象)转化为json数据,下面为代码: public class PageBean <T>{// ...

  2. 关于hibernate中多对多关系

    关于多对多关系 数据库:在使用多对多的关系时,我们能够使用复合主键.也能够不使用,直接引入外键相同能够实现. 在数据库中使用多对多关系时,须要一个中间表. 多对多关系中的数据库结构例如以下: 表:Or ...

  3. hibernate 中多对多关系对象集合的保存

    多对多关系映射和一对多关系映射开发步骤差不多, 例子如下:员工和项目之间的关系,一个员工可以参与多个项目:一个项目可以有多个开发人员参与.因此是多对多的关系. 1 分析数据表 1.1)员工表 CREA ...

  4. 【Hibernate】多对多关系的表达

    User.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate ...

  5. hibernate之多对多关系

    hibernate的多对多hibernate可以直接映射多对多关联关系(看作两个一对多) 下面我们拿三张表来做实例 t_book_hb t_book_category_hb(桥接表) t_catego ...

  6. Hibernate双向多对多对象关系模型映射

    1 双向many-to-many 业务模型: 描述员工和项目 一个员工同时可以参与多个项目 一个项目中可以包含多个员工 分析:数据库的数据模型,通过中间关系表,建立两个one-to-many构成man ...

  7. Hibernate的多对多映射关系

    example: 老师(teacher)和学生(Student)就是一个多对多的关系吧?老师可以有多个学生,学生也可以由多个老师,那在Hibernate中多对多是怎样实现的呢?? 在Hibernate ...

  8. Hibernate的关联映射关系

    一:多对一 <many-to-one 1.name:当前类的属性名(关联映射的类) 2.column:属性多对应的类的对应的表的外键(连接条件) 3.class:属性所对应的类的权限定名 4.n ...

  9. 2.2、Hibernate用注解方式实现一对多、多对多关系

    一.一对多关系 1.在上一篇日志中用.xml配置文件项目基础上,再往lib目录先添加一个包-hibernate-jpa-2.0-api-1.0.0.Final.jar 2.新建一个com.st.bea ...

随机推荐

  1. Redis Sentinel(哨兵核心机制) 初步深入

    ##### 1.Redis 的 Sentinel 系统用于管理多个 Redis 服务 该系统执行以下三个任务:  1.监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务 ...

  2. PTA 7-3 编辑距离问题 (30 分)

    一.实践题目 设A和B是2个字符串.要用最少的字符操作将字符串A转换为字符串B.这里所说的字符操作包括: ()删除一个字符: ()插入一个字符: ()将一个字符改为另一个字符. 将字符串A变换为字符串 ...

  3. SecureCRT连接虚拟机下的CentOS7

    1.首先在VMWare下配置CentOS为桥接模式: 2.查看本机ip: 3.ip addr查看centos的mac地址: 4.在root权限下修改/etc/sysconfig/network-scr ...

  4. Kubernetes快速入门

    二.Kubernetes快速入门 (1)Kubernetes集群的部署方法及部署要点 (2)部署Kubernetes分布式集群 (3)kubectl使用基础 1.简介 kubectl就是API ser ...

  5. Windows渗透测试中wmi的利用

    0x01 关于WMI WMI可以描述为一组管理Windows系统的方法和功能.我们可以把它当作API来与Windows系统进行相互交流.WMI在渗透测试中的价值在于它不需要下载和安装, 因为WMI是W ...

  6. Display 1 No cameras rendering

    解决: 点击Main Camera ,

  7. C# 委托 (一)—— 委托、 泛型委托与Lambda表达式

    C# 委托 (一)—— 委托. 泛型委托与Lambda表达式 2018年08月19日 20:46:47 wnvalentin 阅读数 2992   版权声明:此文乃博主之原创.鄙人才疏,望大侠斧正.此 ...

  8. Vue 上传材料并传给后端接口(使用input)

    最近工作中接到一个需求,需要上传一个文件材料,提交时传给后端.使用的框架是Vue,废话不说直接上代码 <template> <div> <input type=" ...

  9. Js正则学习笔记

    众所周知正则表达式是十分强大的存在,编码时能够熟练使用正则能够极大的简化代码,因此掌握正则非常有必要. 创建正则语法: // 创建正则的两种方式// 1.构造函数 let reg = new RegE ...

  10. Spring Boot 2.X(十一):全局异常处理

    前言 在 Java Web 系统开发中,不管是 Controller 层.Service 层还是 Dao 层,都有可能抛出异常.如果在每个方法中加上各种 try catch 的异常处理代码,那样会使代 ...