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. 【NOIP2016】蚯蚓

    Description 本题中,我们将用符号 ⌊c⌋表示对 cc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀 ...

  2. 使用TryGetComponent取代GetComponent以避免Editor中的内存分配

    作为Unity开发人员,可能或多或少都会遇到过一个常见的Unity的GC分配问题——在Editor中使用GetComponent方法来获取一个不存在的Component时会分配额外的内存.就像下图 需 ...

  3. Vue-CLI 项目在pycharm中配置

    Vue-CLI Vue-CLI 项目在pycharm中配置 第一步 pycharm索引到vue项目的根目录,打开 第二步 安装vue.js插件来高亮 .vue 文件代码(见插图) 第三步 第四步 配置 ...

  4. [LUOGU2964] [USACO09NOV]硬币的游戏A Coin Game

    题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...

  5. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. Intellij IDEA 常用的插件 建议全装

    介绍几个常用的插件 Alibaba Java Coding Guidelines https://plugins.jetbrains.com/plugin/10046-alibaba-java-cod ...

  7. LaTeX常用篇(三)---矩阵与表格

    目录 1. 序言 2. 矩阵 2.1 复杂写法 2.2 简化写法 2.3 复杂矩阵 3. 表格 4. 对齐 更新时间:2019.10.02 1. 序言   矩阵是一个强大的工具,许多东西都能够用矩阵来 ...

  8. CCBPM工作流系统中如何在特定的一个步骤,调用起另外一条流程

    关键词: 工作流快速开发平台  工作流设计  业务流程管理   asp.net 开源工作流bpm工作流系统  java工作流主流框架  自定义工作流引擎 需求描述: 1, 操作员在操作最后一个节点时, ...

  9. Gitlab在Centos7上的安装

    一 官网说明 安装步骤:https://about.gitlab.com/install/#centos-7 安装说明:本文只是用来给微服务当配置中心,只是较浅的记录一下安装步骤,后面会详细讲解及在d ...

  10. sqlite复制表

    (1)复制表,并把原表的 所有记录都复制到新表里. CREATE TABLE newTb AS SELECT * FROM oldTb (2)只复制表结构,不复制数据到新表里. 注:该语句无法复制关键 ...