Hibernate 表关系描述之ManyToMany

 上篇写了一对一,那么在这篇我们讲一对多,那么在表中的一对多,是使用外键关联,通过一张表的一个键另一个表的外键来建立一多关系;
 而在类中表示为一个类中有一个集合属性包含对方类的很多对象,而在另一个类中,只包含前术类的一个对象,从而实现一对多关系的建立!
 而在Hibernate中采用的是Set类型集合,而使用<one-to-many>主<many-to-one>来实现,好了,我们来看一下:
在上一篇中讲到一对多,那么在此补充一下多对多;
在数据库中也有多对多的关系,数据中的实现方式一般是采用存在多对多关系的两个对对象表,建立多对多关联表,也就是用一个独立的表来存入两个表的主键字段,通过遍历这张表来获取两表的关联关系。
而在我们的对象中,多对多是通过两者对象类中互相建立对方类的对象集合,类似上一篇讲到的一对多的集合类!
在Hibernate中当然就是通过<many to many>了
我们现在来通过一个案例来学习。学生与老师关系,是多对多。一个学生可以有多个老师,而一个老师也一样可以有多名学生!
Step1:首先建立我们需要的表,如下:

None.gif create   table  teachers
None.gif(
None.gif    teaID 
bigint  auto_increment  primary   key ,
None.gif    teaName 
varchar ( 20 )
None.gif);
None.gif
None.gif
create   table  students
None.gif(
None.gif    stuID 
bigint   primary   key  auto_increment,
None.gif    sName 
varchar ( 20 )
None.gif);
None.gif
None.gif
-- 关联表   学生与教师
None.gif
create   table  student_teacher_table
None.gif(
None.gif    teaID 
int ,
None.gif    stuID 
int
None.gif);
Step2:新建一个HibernateManyToMany项目 ,并添加hibernate。
Step3:我们将前面创建的teachers表和students表导向到Beans中,注意这里的关系表 student_teacher_table并不导出!因为我们数据做持久,持久的是对象,而不是关系, student_teacher_table表存放的是关系,所以我们不需要将 其导出,那么使用呢?接着看吧!
Step4:现在我们开始类对象关系的描述,我们先打开生成的Student.java 在里面添加Set 教师集合,然后在Teachers.java中同样添加Set学生集合!
Step5:我们描述了类与类之间的关系后,剩下的就是让Hibernate知道它们之间的关系,分别修改学生和教师类映射文件!
student.hbm.xml内容如下:
None.gif <? xml version="1.0" encoding="GBK" ?>
None.gif
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
None.gif"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
None.gif
<!--  
None.gif   Autho:fengyan
None.gif   date: 2006-12-30 17:04
None.gif
-->
None.gif
< hibernate-mapping >
None.gif    
< class  name ="hibernate.beans.Students"  table ="students"  catalog ="study" >
None.gif        
< id  name ="stuId"  type ="java.lang.Long" >
None.gif            
< column  name ="stuID"   />
None.gif            
< generator  class ="native"   />
None.gif        
</ id >
None.gif        
< property  name ="sname"  type ="java.lang.String" >
None.gif            
< column  name ="sName"  length ="20"   />
None.gif        
</ property >
None.gif        
None.gif        
< set  name ="teachers"  table ="student_teacher_table"  cascade ="save-update"  inverse ="false" >
None.gif            
None.gif            
< key  column ="stuID" ></ key >
None.gif            
<!--
None.gif            它的控制主要是通过stuid来选择,就是我们从student_teacher_table表中我们只
None.gif            要select *  from student_teacher_table where  stuID='该学生ID',这样我
None.gif            们就可以获取它的教师的ID了
None.gif             
-->
None.gif         
None.gif             
< many-to-many  class ="hibernate.beans.Teachers"  column ="teaID" ></ many-to-many >
None.gif             
<!--  
None.gif             我们从student_teacher_table表中根据stuID拿到了与该stuID关联的teaID,
None.gif             然后 select * from teacher where teaID='前一步拿到的teaID' 
-->
None.gif        
</ set >
None.gif    
</ class >
None.gif
</ hibernate-mapping >

再看teacher.hbm.xml文件内容:
None.gif <? xml version="1.0" encoding="GBK" ?>
None.gif
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
None.gif"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
None.gif
<!--  
None.gif   Authod:fengyan
None.gif   date:  2006-12-30 17:10
None.gif
-->
None.gif
< hibernate-mapping >
None.gif    
< class  name ="hibernate.beans.Teachers"  table ="teachers"  catalog ="study" >
None.gif        
< id  name ="teaId"  type ="java.lang.Long" >
None.gif            
< column  name ="teaID"   />
None.gif            
< generator  class ="native"   />
None.gif        
</ id >
None.gif        
< property  name ="teaName"  type ="java.lang.String" >
None.gif            
< column  name ="teaName"  length ="20"   />
None.gif        
</ property >
None.gif        
None.gif        
<!--  前面在student中已经级联了,所以这里我没有再级联,简单的演示!  -->
None.gif        
< set  name ="students"  table ="student_teacher_table"  inverse ="true" >
None.gif            
< key  column ="teaID" ></ key >
None.gif            
< many-to-many  class ="hibernate.beans.Students"  column ="stuID" ></ many-to-many >
None.gif        
</ set >
None.gif    
</ class >
None.gif
</ hibernate-mapping >

然后我们现在建立一个StudentDAO.java用来封装操作:
ContractedBlock.gif ExpandedBlockStart.gif StudentDAO.java
None.gifpackage hibernateDAOS;
ExpandedBlockStart.gifContractedBlock.gif
/** *//**
InBlock.gif * Authod:fengyan
InBlock.gif * date:   2006-12-30 17:15    
ExpandedBlockEnd.gif 
*/

None.gif
import hibernate.HibernateSessionFactory;
None.gif
import hibernate.beans.Students;
None.gif
None.gif
import org.hibernate.Session;
None.gif
import org.hibernate.Transaction;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public class StudentsDAO dot.gif{
InBlock.gif    
public void save(Students student)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        Session session 
= HibernateSessionFactory.getSession();        
InBlock.gif        Transaction tx 
= session.beginTransaction();
InBlock.gif        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            session.save(student);
InBlock.gif            tx.commit();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch(Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            System.out.println(
"stuDAO has errors:"+e);
InBlock.gif            tx.rollback();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            session.close();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

Step6:建立一个Servlet,MyServlet.java;
ContractedBlock.gif ExpandedBlockStart.gif MyServlet.java
None.gifpackage hibernate.servlet;
None.gif
None.gif
import hibernate.beans.Students;
None.gif
import hibernate.beans.Teachers;
None.gif
import hibernateDAOS.StudentsDAO;
None.gif
None.gif
import java.io.IOException;
None.gif
None.gif
import javax.servlet.ServletException;
None.gif
import javax.servlet.http.HttpServlet;
None.gif
import javax.servlet.http.HttpServletRequest;
None.gif
import javax.servlet.http.HttpServletResponse;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public class MyServlet extends HttpServlet dot.gif{
InBlock.gif
InBlock.gif
InBlock.gif    
public void doGet(HttpServletRequest request, HttpServletResponse response)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
throws ServletException, IOException dot.gif{
InBlock.gif        
InBlock.gif        
//产生学生
InBlock.gif
        Students s1 = new Students("学生1");
InBlock.gif        Students s2 
= new Students("学生2");
InBlock.gif        
InBlock.gif        
//产生教师
InBlock.gif
        Teachers t1 = new Teachers("教师1");
InBlock.gif        Teachers t2 
= new Teachers("教师2");
InBlock.gif        Teachers t3 
= new Teachers("教师3");
InBlock.gif        Teachers t4 
= new Teachers("教师4");
InBlock.gif        
InBlock.gif        
//学生关联教师(学生选择教师)
InBlock.gif
        s1.getTeachers().add(t1);
InBlock.gif        s1.getTeachers().add(t2);
InBlock.gif        
//学生 s1 选择 t1 及 t2 二名教师
InBlock.gif

InBlock.gif        s2.getTeachers().add(t1);
InBlock.gif        s2.getTeachers().add(t3);
InBlock.gif        
//学生 s2 选择 t1 及 t3 二名教师
InBlock.gif        
InBlock.gif        
//我们保存学生 s1及 s2
InBlock.gif
        StudentsDAO sd = new StudentsDAO();
InBlock.gif        sd.save(s1);
InBlock.gif        sd.save(s2);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

Step7:最后来个测试index.jsp页面
None.gif < href ="servlet/MyServlet" > add  </ a >

运行 结果:



由图片可知,
第一步:首先将 “学生1”插入students表中;
第二步:将"学生1"关联的“教师1”插入到teachers表中;
第三步:将“学生1”关联的“教师2”插入到teachers表中;
第四步:将“学生1”与“教师1”的关联信息(1,1)插入到student_teacher_table表中;
第五步:将“学生1”与“教师2”的关联信息(1,2)插入到student_teacher_table表中;
第六步:将“学生2”插入students表中;
第七步:将“教师3”插入teachers表中;
第八步:更新?更新了“学生2”关联~这步有点不解
第九步:将“学生2”与“教师1”的关联信息(2,1)插入到student_teacher_table表中;
第十步:将“学生2”与“教师3”的关联信息(2,3)插入student_teacher_table表中;

总结:感觉多对多与一对多基本是差不多的~至于每次示例中仅仅是简单的save,,而没其它的操作,是由于打算以后将在SSH项目中运用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值