说到多对多关系,印象最深刻的就是大学的选修课。一个学生可以选修多门课程,一门课程可以有多个学生选修,学生所选的每一门课程还有成绩。这个场景的E-R图如下:

对于多对多的关系,我们通常会抽出一张中间表(连接表),来负责维护这两张表的多对多关系,比如上述关系应该生成的表结构为:

PO对象

   Student.java

package entity;

import java.util.Set;

public class Students {
private int id ;
private String name;
private Set<Course>courses;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
} }

Course.java

package entity;

import java.util.Set;

public class Course {
private int id;
private String name;
private Set<Students> students;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Students> getStudents() {
return students;
}
public void setStudents(Set<Students> students) {
this.students = students;
} }

映射文件

Students.hnm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name ="entity.Students" table="t_students">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="Courses" table="t_singup">
<key column="student_id"/>
<!-- 多个学生id对应对个course_id -->
<many-to-many class="entity.Course" column="course_id"></many-to-many>
</set>
</class>
</hibernate-mapping>

配置文件中的set对应于相应类中的集合,key是指向多的一方的外键,对应t_score表中的course_id。

Course.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Course" table="t_course">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" table="t_signup" inverse="true">
<key column="course_id"/>
<many-to-many class="entity.Students" column="student_id"/>
</set>
</class>
</hibernate-mapping>

运行代码执行的建表语句为:

drop table  t_course
drop table t_signup
drop table t_students create table t_course (id integer primary key , name varchar(255));
create sequence course
minvalue 1 --最小值
nomaxvalue --不设置最大值
start with 1 --从1开始计数
increment by 1 --每次加1个
nocycle --一直累加,不循环
nocache --不建缓冲区
create or replace trigger course_tg
before insert on t_course for each row when(new.id is null)
begin
select course.nextval into:new.id from dual;
end;
create table t_signup (student_id integer , course_id integer ,constraint zhujian primary key (student_id, course_id));
drop sequence students;
create table t_students (id integer , name varchar(255), primary key (id));
create sequence students
minvalue 1 --最小值
nomaxvalue --不设置最大值
start with 1 --从1开始计数
increment by 1 --每次加1个
nocycle --一直累加,不循环
nocache ;--不建缓冲区
create or replace trigger students_tg
before insert on t_students for each row when(new.id is null)
begin
select students.nextval into:new.id from dual;
end;
create index FK7DADC3438FFF3382 on t_signup(student_id);
alter table t_signup add constraint FK7DADC3438FFF3382 foreign key(student_id) references t_students(id);
create index FK7DADC3438CBEF332 on t_signup(course_id);
alter table t_signup add constraint FK7DADC3438CBEF332 foreign key(course_id) references t_course(id);

生成的表结构如下:

t_signup中生成了复合主键,student_id和course_id分别是指向t_students和t_course的外键。

插入测试

session.beginTransaction();

Course course1=new Course();
course1.setName("《心理应激微反应》");
session.save(course1);
Course course2=new Course();
course2.setName("《哈利·波特与遗传学》");
session.save(course2);
Course course3=new Course();
course3.setName("《三国杀攻略教程》");
session.save(course3);
Course course4=new Course();
course4.setName("《寄生虫与寄生虫病视频欣赏》");
session.save(course4); Student student1=new Student();
Set courses1=new HashSet();
courses1.add(course1);
courses1.add(course2);
student1.setCourses(courses1);
student1.setName("小胡");
session.save(student1); Student student2=new Student();
Set courses2=new HashSet();
courses2.add(course3);
courses2.add(course4);
student2.setCourses(courses2);
student2.setName("小玉");
session.save(student2); Student student3=new Student();
Set courses3=new HashSet();
courses3.add(course1);
courses3.add(course2);
courses3.add(course3);
courses3.add(course4);
student3.setCourses(courses3);
student3.setName("小洋");
session.save(student3); session.getTransaction().commit();

插入结果:

  但是上述方法并不适合给多对多的关系添加额外的属性,那怎么办呢?可以用两个一对多关系来实现,即可以手动将中间表设计成一个实体,并为其配置映射关系,所以通常情况下,一个多对多关系也可以用两个一对多关系来实现。

Hibernate学习(五)Hibernate 多对多映射的更多相关文章

  1. hibernate 学习 五 hibernate核心接口

    一 Configuration接口 Configuration对象只存在于系统的初始化阶段.配置相关. 配置文件可以使用默认的路径,也可以指定路径. Configuration config = ne ...

  2. Hibernate学习之单向多对一映射

    © 版权声明:本文为博主原创文章,转载请注明出处 说明:该实例是通过映射文件和注解两种方式实现的.可根据自己的需要选择合适的方式 实例: 1.项目结构 2.pom.xml <project xm ...

  3. hibernate学习五 Hibernate补充

    1  MiddleGenIDE可以生成映射类和映射文件. 2

  4. Hibernate学习8—Hibernate 映射关系(多对多)

    第二节:Hibernate 多对多映射关系实现   比如学生和课程是多对多的关系: 一个学生可以选多个课程: 一个课程可以被多个学生选中,所以是多对多的关系:   1,多对多单向实现: 单向关系: 这 ...

  5. Hibernate学习7—Hibernate 映射继承

    需求:学生有很多照片,分为生活照和工作照: 第一节:每个具体类对应一个表 Student.java: package com.cy.model; import java.util.Set; publi ...

  6. Hibernate学习之——Hibernate环境搭建

    之前在写关于安卓闹钟的教程,写了一半就没后一半了,其实自己也没做好,在校外实习,校内毕业实习又有任务,只能先放放了,等毕业实习结束之后,在继续安卓闹钟开发之旅,相信这个时间不会很久的.现在毕业实习用到 ...

  7. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...

  8. Hibernate学习0.Hibernate入门

    Hibernate是什么 面向java环境的对象/关系数据库映射工具. 1.开源的持久层框架. 2.ORM(Object/Relational Mapping)映射工具,建立面向对象的域模型和关系数据 ...

  9. hibernate学习之Hibernate API

    1. Hibernate Api分类 1)提供访问数据库的操作(如保存,更新,删除,查询)的接口.这些接口包括:Session, Transaction,,Query接口. 2)由于配置Hiberna ...

随机推荐

  1. (转)linux下如何批量杀JAVA进程或某个进程方法

    在工作中经常需要停止JAVA进程,停止时间也比较长,那么有时候因为一些情况,需要把 linux 下JAVA所有进程 kill 掉,又不能用killall 直接杀掉某一进程名称包含的所有运行中进程(我们 ...

  2. NumPy基础练习(练一遍搞定NumPy)

    import numpy as np import pandas as pd from numpy import random from numpy.random import randn ##### ...

  3. scrollWidth,clientWidth,offsetWiddth,innerWinth 元素定位

    getBoundingClientRect()方法.它返回一个对象,其中包含了left.right.top.bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左 ...

  4. .Net高级进阶,在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码?

    本文将通过场景例子演示,来通俗易懂的讲解在复杂的业务逻辑下,如何以最简练的代码,最直观的编写事务代码. 通过一系列优化最终达到两个效果,1.通过代码块来控制事务(分布式事务),2.通过委托优化Tran ...

  5. 1045-access denied for user 'root'@

    在用sqlyog图形界面远程登录阿里云mysql数据库的时候出现了如下的问题, 1045-access denied for user 'root'@ 刚开始以为阿里云esc的安全组并没有配置3306 ...

  6. Promise同时进入catch和then——踩坑

    记录今天使用Promise遇到的一个坑--在resolve()返回运行then之后,函数又进入到了catch,源代码大意如下: var pro = function() { return new Pr ...

  7. Node学习笔记 http

    node url querystring 第二个参数指定分隔符 也可以指定三个参数,效果和两个参数类似 不同于querystring,下面是querystringfy的用法 queryescape与e ...

  8. HTML5 Web缓存&运用程序缓存&cookie,session

    在介绍HTML5 web缓存前,来认识一下cookie和session: session: 由于HTTP是无状态的,你是谁?你干了什么?抱歉服务器都是不知道的. 因此session(会话)出现了,它会 ...

  9. 前端使用d3.js调用地图api 进行数据可视化

    前段时间自己研究了demo就是把某个区域的某个位置通过经纬度在地图上可视化.其实就是使用了第三方插件,比现在比较火的可视化插件d3.js echart.js.大致思路就是,把要用到的位置的geojso ...

  10. Oracle漏洞分析(tns_auth_sesskey)

    p216 Oracle漏洞分析: 开启oracle: C:\oracle\product\\db_1\BIN\sqlplus.exe /nolog conn sys/mima1234 as sysdb ...