第七章 多对多

 多对多

什么情况下会出现多对多呢?比如学生选课就会出现多对多的情况,那么我们在数据库层面是怎么解决这种问题的呢,通常会有三张表,
学生表
ID 学生姓名
1 张三
2 李四
3 王五

课程表
ID 课目名
1 Java
2 SQL
3 JavaScript

学生_课程表
ID 学生ID 课目ID
1 2 1
2 2 3
3 3 2
4 3 1
5 1 1
6 1 2
7 1 3

那么从学生_课程的表中我们只需要知道学生ID,或者科目ID,便可以清楚的查询出每个学生选修的科目,以及指定的科目被哪些学生选修了.

那么这种情况反映到Hibernate中呢,是怎么对应呢?
在Hibernate中,多对多,其实是多个一对多.
但是在定位哪是多,哪是一的问题上,你需要站在学生或者科目的角度来考虑,
比如
学生角度,学生张三现在修了哪几门科目,那么学生张三是一, 科目是多,所以学生类中应该持有一个科目集合
科目角度,Java这门课被哪几个学生选修过,那么这时科目应该是一,学生是多,那么这时,科目类中就应该持有一个学生集合
但是所持有的科目集合或学生集合又不是直接对应的集合,而是所谓中间表(学生_课程表)对应的类集合.

请看下面的代码实现:
Model层:
Student:
public class Student {

private String id;
private String stuName;
private Set<StuSub> stuSubs = new HashSet<StuSub>();

public Student() {
}

public Student(String stuName) {
super();
this.stuName = stuName;
}

public Student(String stuName, Set<StuSub> stuSubs) {
this.stuName = stuName;
this.stuSubs = stuSubs;
}

public String getId() {
return this.id;
}

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

public String getStuName() {
return this.stuName;
}

public void setStuName(String stuName) {
this.stuName = stuName;
}

public Set<StuSub> getStuSubs() {
return this.stuSubs;
}

public void setStuSubs(Set<StuSub> stuSubs) {
this.stuSubs = stuSubs;
}
}

Subject:
public class Subject {
private String id;
private String subName;
private Set<StuSub> stuSubs = new HashSet<StuSub>();

public Subject() {
}

public Subject(String subName) {
super();
this.subName = subName;
}

public Subject(String subName, Set<StuSub> stuSubs) {
this.subName = subName;
this.stuSubs = stuSubs;
}

public String getId() {
return this.id;
}

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

public String getSubName() {
return this.subName;
}

public void setSubName(String subName) {
this.subName = subName;
}

public Set<StuSub> getStuSubs() {
return this.stuSubs;
}

public void setStuSubs(Set<StuSub> stuSubs) {
this.stuSubs = stuSubs;
}
}

StuSub:
public class StuSub {
private String id;
private Student student;
private Subject subject;

public StuSub() {
}

public StuSub(Student student, Subject subject) {
this.subject = subject;
this.student = student;
}

public String getId() {
return this.id;
}

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

public Subject getSubject() {
return this.subject;
}

public void setSubject(Subject subject) {
this.subject = subject;
}

public Student getStudent() {
return this.student;
}

public void setStudent(Student student) {
this.student = student;
}
}

映射文件:
Student.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="chapter4.model.Student" table="student">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="stuName" type="java.lang.String">
<column name="stuName" length="20" />
</property>
<set name="stuSubs">
<key>
<column name="stu_id" length="32" />
</key>
<one-to-many class="chapter4.model.StuSub" />
</set>
</class>
</hibernate-mapping>

Subject.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="chapter4.model.Subject" table="subject">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="subName" type="java.lang.String">
<column name="subName" length="20" />
</property>
<set name="stuSubs">
<key>
<column name="sub_id" length="32" />
</key>
<one-to-many class="chapter4.model.StuSub" />
</set>
</class>
</hibernate-mapping>

StuSub.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="chapter4.model.StuSub" table="stu_sub">
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<generator class="uuid.hex"/>
</id>
<many-to-one name="subject" class="chapter4.model.Subject">
<column name="sub_id" length="32" />
</many-to-one>
<many-to-one name="student" class="chapter4.model.Student">
<column name="stu_id" length="32" />
</many-to-one>
</class>
</hibernate-mapping>

Dao层:
StudentDao:
public class StudentDao {
public void create(Student student) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(student);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public Student findById(Serializable id) throws Exception {
Session session = null;
Student student = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
student = (Student) session.get(Student.class, id);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return student;
}
}

SubjectDao:
public class SubjectDao {
public void create(Subject subject) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(subject);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public Subject findById(Serializable id) throws Exception {
Session session = null;
Subject subject = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
subject = (Subject) session.get(Subject.class, id);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return subject;
}
}

StuSubDao:
public class StuSubDao {
public void create(StuSub stuSub) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(stuSub);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}

public StuSub findById(Serializable id) throws Exception {
Session session = null;
StuSub stuSub = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
stuSub = (StuSub) session.get(StuSub.class, id);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return stuSub;
}
}

测试文件:
Test:
public class Test {
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
StuSubDao stuSubDao = new StuSubDao();
SubjectDao subjectDao = new SubjectDao();

//创建两个学生
Student student1 = new Student("张三");
Student student2 = new Student("李四");

//创建三门科目
Subject subject1 = new Subject("java");
Subject subject2 = new Subject("sql");
Subject subject3 = new Subject("javaScript");

//张三报了三门课
StuSub stuSub1 = new StuSub(student1, subject1);
StuSub stuSub2 = new StuSub(student1, subject2);
StuSub stuSub3 = new StuSub(student1, subject3);

//李四报了二门课
StuSub stuSub4 = new StuSub(student2, subject1);
StuSub stuSub5 = new StuSub(student2, subject2);

//保存学生入库
studentDao.create(student1);
studentDao.create(student2);

//保存科目入库
subjectDao.create(subject1);
subjectDao.create(subject2);
subjectDao.create(subject3);

//保存张三选修的科目入库
stuSubDao.create(stuSub1);
stuSubDao.create(stuSub2);
stuSubDao.create(stuSub3);

//保存李四选修的科目入库
stuSubDao.create(stuSub4);
stuSubDao.create(stuSub5);

//知道张三的ID,查找张三选修了哪几门科目
Student student = studentDao.findById("40285c8127aa1e9d0127aa1e9ed50001");
Set<StuSub> set1 = student.getStuSubs();
for(StuSub stuSub : set1){
System.out.println(stuSub.getSubject().getSubName());
}

//知道Java科目的ID,查找有哪些人修过Java科目
Subject subject = subjectDao.findById("40285c8127aa1e9d0127aa1e9fbf0005");
Set<StuSub> set2 = subject.getStuSubs();
for(StuSub stuSub : set2){
System.out.println(stuSub.getStudent().getStuName());
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值