hibernate 多对多操作


关键字: hibernate 多对多操作


多对多的两种映射形式:
一。映射多对多关系
老师Teacher 与 课程Course 是一个多对多的关系,XMl配置如下。
三个表的表结构

1. tbl_course.sql 
  
    create table "SCOTT"."TBL_COURSE"( 
  
        "ID" CHAR(32) not null, 
  
       "NAME" VARCHAR2(20) not null, 
  
        constraint "SYS_C005315" primary key ("ID") 
  
    ); 
  
2. tbl_teacher.sql 
  
    create table "SCOTT"."TBL_TEACHER"( 
  
        "ID" CHAR(32) not null, 
  
       "NAME" VARCHAR2(20) not null, 
  
        constraint "SYS_C005313" primary key ("ID") 
  
    ); 
  
3.tbl_teacher_course.sql 
  
  create table "SCOTT"."TBL_TEACHER_COURSE"( 
  
        "TID" CHAR(32), 
  
       "CID" CHAR(32) 
  
    ); 
  

Teacher.hbm.xml 
  
<hibernate-mapping> 
  
    <class name="mapping.Teacher" table="teacher" schema="dbo" catalog="Student"> 
  
        <id name="id" type="string"> 
  
            <column name="ID" length="32" /> 
  
            <generator class="uuid" /> 
  
        </id> 
  
        <property name="name" type="string"> 
  
            <column name="Name" length="50" not-null="true" /> 
  
        </property> 
  
        <set access="property" name="courses" lazy="true" inverse="true"  
  
             
  cascade="save-update"  batch-size="10" fetch="select"  
  
             table="teacher_course">  
  
             <key column="TID" /> 
  
             <many-to-many class="mapping.Course1" column="CID" />  
  
         </set>  
  
    </class> 
  
</hibernate-mapping> 
  

COURSE.hbm.xml 
  
<hibernate-mapping> 
  
    <class name="mapping.Course" table="course" schema="dbo" catalog="Student"> 
  
        <id name="id" type="string"> 
  
            <column name="ID" length="32" /> 
  
            <generator class="uuid" /> 
  
        </id> 
  
        <property name="cname" type="string"> 
  
            <column name="cname" length="50" /> 
  
        </property> 
  
        <set access="property" name="teachers" lazy="true" 
  inverse="false"  
  
             cascade="save-update"  batch-size="10" fetch="select"  table="teacher_course">  
  
             <key column="CID" /> 
  
             <many-to-many class="mapping.Teacher" column="TID" />  
  
         </set> 
  
    </class> 
  
</hibernate-mapping>




1. 如果cascade 不管主控方设置还是被控方设置成all或delete,级联删除时,两端以及中间表的记录都会被删除,通常这样的需要是很少的。

2. 只想删除某一端的记录以及中间的表的关联信息。 这种需求通常是很常见的。这个时候cascade的设置是除与delete有关的任何级联约束。以下是删除心得:

2.1 通过主控方来删除

/**  
  
* 多对多 主控方删除(可以删除中间表记录)  
  
*/    
  
Session session = HibernateSessionFactory.getSession();  
  
session.beginTransaction(); 
  
     
  
String cid = "2c2880d12041c65f012041c665180001"; 
  
Course course1 = (Course) session.get(Course.class , cid);  
  
session.delete(course1); 
  
session.getTransaction().commit();  
  
session.close(); 
  

2.2 通过被控方来删除 
  
/**  
  
* 多对多 被控方删除(无法删除中间表记录)  
  
*/    
  
String id = "402881ee175a2e7c01175a2e7ead0003" ;  
  
Session session = HibernateSessionFactory.getSession();  
  
session.beginTransaction();  
  
Teacher t1 = (Teacher) session.get(Teacher.class , id);  
  
session.delete(t1);  
  
session.getTransaction().commit();  
  
session.close();  
  

/**  
  
* 多对多 被控方删除(可以删除中间表记录)   
  
*/    
  
String id = "402881ee175a2e7c01175a2e7ead0003" ;  
  
Session session = HibernateSessionFactory.getSession();  
  
session.beginTransaction();  
  
Teacher t1 = (Teacher) session.get(Teacher.class , id); 
  

Set<Course> cs = t1.getCourses();  
  
for  (Course c : cs) {  
  
    c.getTeachers().remove(t1);  
  
}  
  
session.delete(t1);  
  
session.getTransaction().commit();  
  
session.close();   
  


二。映射为两个一对多关系 
  
三个表结构如下: 
  
CREATE TABLE [dbo].[student] ( 
  
 [id] [bigint] IDENTITY (1, 1) NOT NULL , 
  
 [sno] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL , 
  
 [sname] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL , 
  
 [gender] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL 
  
) ON [PRIMARY] 
  

CREATE TABLE [dbo].[score] ( 
  
 [id] [bigint] IDENTITY (1, 1) NOT NULL , 
  
 [cid] [bigint] NULL , 
  
 [sid] [bigint] NULL , 
  
 [scgrade] [float] NOT NULL 
  
) ON [PRIMARY] 
  

CREATE TABLE [dbo].[course] ( 
  
 [id] [bigint] IDENTITY (1, 1) NOT NULL , 
  
 [cno] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL , 
  
 [cname] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL 
  
) ON [PRIMARY] 
  

Student.hbm.xml 
  
<hibernate-mapping> 
  
    <class name="mapping.Student" table="student" schema="dbo" catalog="Student"> 
  
        <id name="id" type="java.lang.Long"> 
  
            <column name="id" /> 
  
            <generator class="identity" /> 
  
        </id> 
  
        <set name="scores" cascade="all" inverse="true"  table="score" > 
  
            <key> 
  
                <column name="sid" not-null="true"  /> 
  
            </key> 
  
            <one-to-many class="mapping.Score" /> 
  
        </set> 
  
    </class> 
  
</hibernate-mapping> 
  

Score.hbm.xml 
  
<hibernate-mapping> 
  
    <class name="mapping.Score" table="score" schema="dbo" catalog="Student"> 
  
        <id name="id" type="java.lang.Long"> 
  
            <column name="id" /> 
  
            <generator class="identity" /> 
  
        </id> 
  

        <many-to-one name="course" class="mapping.Course" > 
  
            <column name="cid"  /> 
  
        </many-to-one> 
  
        <many-to-one name="student" class="mapping.Student" > 
  
            <column name="sid" /> 
  
        </many-to-one> 
  
    </class> 
  
</hibernate-mapping> 
  


Course.hbm.xml 
  
<hibernate-mapping> 
  
    <class name="mapping.Course" table="course" schema="dbo" catalog="Student"> 
  
        <id name="id" type="java.lang.Long"> 
  
            <column name="id" /> 
  
            <generator class="identity" /> 
  
        </id> 
  
        <set name="scores" cascade="all" inverse="true"  table="score"> 
  
            <key> 
  
                <column name="cid" not-null="true" /> 
  
            </key> 
  
            <one-to-many class="mapping.Score" /> 
  
        </set> 
  
    </class> 
  
</hibernate-mapping> 
  

/**  
  
* 一对多 被控方删除(可以删除中间表记录)   学生 
  
*/  
  
Long lid = Long.valueOf("19"); 
  
Session session = HibernateSessionFactory.getSession(); 
  
session.beginTransaction(); 
  
Student student = (Student)session.get(Student.class, lid); 
  
session.delete(student);  
  
session.getTransaction().commit(); 
  
session.close(); 
  

/**  
  
* 一对多 被控方删除(可以删除中间表记录)   课程 
  
*/ 
  
Long lid = Long.valueOf("19"); 
  
Session session = HibernateSessionFactory.getSession(); 
  
session.beginTransaction(); 
  
Course course = (Course)session.get(Course.class, lid); 
  
session.delete(course);  
  
session.getTransaction().commit(); 
  
session.close();



另外从网上收集了一些资料,进行了整理, 附件内容包括一对一,一对多,多对多类型映射及详细说明。希望对学习hibernate的朋友有所帮助。