(Hibernate)cascade

利用关联关系操作对象:
数据对象之间的关联关系有一对一,一对多及多对多三种。在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难。例如,当删除一个班级的信息时,还要删除该班级的所有学生的基本信息。如果直接使用JDBC执行这种级联操作,会非常繁锁。Hibernate通过把实体对象之间的关联关系及级联关系在映射文件中声明,比较简单地解决了这类级联操作问题。
一对一关联关系的使用
一对一关联关系在实际生活中是比较觉的,例如学生与学生证的关系,通过学生证可以找到学生。一对一关联关系在Hibernate中的实现有两种方式,分别是主键关联和外键关联。
主键关联
主键关联的重点是,关联两个实体共享一个主键值。例如student与card是一对一关系,它们在数据库中对应的表分别是t_student和 t_card。它们共用一个主键值ID,这个主键可由t_student或t_card表生成。问题是如何让另一张表引用已经生成的主键值呢?例如,t_student表未老先衰了ID的值,t_card表如何引用它?这需要在Hibernate的映射文件中使用主键的foreign生成机制!

为了表示Student与Card之间的一对一的关联关系,我们需要在它们各自的映射文件 中都要使用标记!
一对一关系我在前面已经写过例子程序了,在这里仅给出两个映射文件。如下:
学生PO映射信息:

xml version="1.0" encoding="GBK" ?>
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

< hibernate-mapping >
    
< class  name ="hibernate.PO.TStudent"  table ="t_student"  lazy ="true" >
        
< id  name ="id"  type ="java.lang.Integer" >
            
< column  name ="id" />
            
< generator  class ="increment"   />
        
id >
        
< property  name ="userName"  type ="java.lang.String" >
            
< column  name ="userName"  length ="20"   />
        
property >
        
< property  name ="cardId"  type ="java.lang.String" >
            
< column  name ="card_id"  length ="20"   />
        
property >
        
< property  name ="sex"  type ="java.lang.String" >
            
< column  name ="sex"  length ="2"   />
        
property >
        
< property  name ="age"  type ="java.lang.Integer" >
            
< column  name ="age"   />
        
property >
        
< one-to-one  name ="card"  class ="hibernate.PO.TCard"  fetch ="join"  cascade ="all"   />
    
class >
hibernate-mapping >


学生证PO映射信息:

xml version="1.0" encoding="GBK" ?>
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

< hibernate-mapping >
    
< class  name ="hibernate.PO.TCard"  table ="t_card"  lazy ="true" >
        
< id  name ="id"  type ="java.lang.Integer" >
            
< column  name ="id" />
            
< generator  class ="foreign" >
                
< param  name ="property" > student param >
            
generator >
        
id >
        

        
< property  name ="name"  type ="java.lang.String" >
            
< column  name ="name"  length ="20"   />
        
property >
       
          
          
< one-to-one  name ="student"  class ="hibernate.PO.TStudent"  constrained ="true"   />         
          

    
class >
hibernate-mapping >

 

外键关联
外键关联的要点是:两个实体各自有不同的主键,但其中一个实体有一个外键引用另一个实体的主键。例如,假设,Student和Card是外键关联的一对一关系们在数据库中相应的表分别如下:t_student表有一个主键ID,t_card表有一个主键ID和一个外键student_id,此外键对应 t_student表的主键ID,那么student的映射信息如上面一样不做改动,而Card的映射文件要做相应的改动。如下:
< hibernate-mapping >
    
< class  name ="hibernate.PO.TCard"  table ="t_card"  lazy ="true" >
        
< id  name ="id"  type ="java.lang.Integer" >
            
< column  name ="id" />
            
< generator  class ="increment" />                  
        
id >
        
        
< property  name ="name"  type ="java.lang.String" >
            
< column  name ="name"  length ="20"   />
        
property >
       
       
< many-to-one  name ="student"  column ="student_id"  class ="hibernate.PO.TStudent"  unique ="true" />
       

         

           
    
class >
hibernate-mapping >

一对多关联关系的使用
一对多关系很觉,例如班级与学生的关系就是典型的一对多的关系。在实际编写程序时,一对多关系有两种实现方式:单向关联和双向关联。单向的一对多关系只需要在一方进行映射配置,而双向的一对多需要在关联的双方进行映射配置。下面以Group(班级)和Student(学生)为例讲解如何配置一对多的关系。
单向关联
单向的一对多关系只需要在一方进行映射配置,所以我们只配置Group的映射文件:
< hibernate-mapping >
    
< class  name ="hibernate.PO.Group"  table ="t_group"  lazy ="true" >
        
< id  name ="id"  type ="java.lang.Integer" >
            
< column  name ="id" />
            
< generator  class ="increment" />                  
        
id >
        

        
< property  name ="name"  type ="java.lang.String"  update ="true"  insert ="true" >
            
< column  name ="name"  length ="20"   />
        
property >
        
        

        
< set  name ="students"  
             table
="t_student"  
             lazy
="true"  
             inverse
="false"  
             cascade
="all"  
             sort
="unsorted" >
        
< key  column ="ID" />
        
< one-to-many  class ="hibernate.PO.TStudent" />         
        
set >
    
class >
hibernate-mapping >
双向关联
如果要设置一对多双向关联关系,那么还需要在“多”方的映射文件中使用标记。例如,在Group与Student一对多的双向关联中,除了Group的映射文件外还需要在Student的映射文件中加入如下代码:
  < many-to-one  name ="group"
                     class
="Group"
                     cascade
="none"
                     outer-join
="auto"
                     update
="true"
                     insert
="true"
                     column
="ID"   />

inert和update设定是否对column属性指定的关联字段进行insert和update操作。
此外将Group.hbm.xml中元素的inverse设置为true.

多对多关联关系的使用
Student(学生)和Course(课程)的关系就是多对多关系。在映射多对多关系时需要另外使用一个连接表(如Student_Course)。 Student_Course表包含二个字段:courseID和studentID。此处它们的映射文件中使用标记,在Student的映射文件中加入以下描述信息:

   < set  name ="courses"  
               table
="student_course"  
               lazy
="false"  
               inverse
="false"
               cascade
="save-update" >
               
< key  column ="studentID"   />
           
< many-to-many  class ="Course"  column ="CourseID" />     
           
set >
相应的Course的映射文件中加入以下:
  < set  name ="students"  
               table
="student_course"  
               lazy
="false"  
               inverse
="true"
               cascade
="save-update" >
               
< key  column ="CourseID"   />
           
< many-to-many  class ="Student"  column ="StudentID" />     
           
set >
添加关联关系
首先编写一个程序来看看一个名为Bill的学生选择了什么课程:
// 获取代表Bill的Student对象
        Student stu  =  (Student)session.createQuery( " from Student s where s.name='Bill' " ).uniqueResult();
        List list 
=   new  ArrayList(stu.getCourses());
        
for ( int  i  =   0  ; i  <  list.size(); i ++ )
        
{
            Course course 
= (Course)list.get(i);//取得Course对象
            System.out.println(course.getName());//打印出Bill所选课程的清单
        }
现在Bill还想chemistry课程,这对于程序员来说只是为Bill添加一个到chemistry的关联,也就是说在student_course表中新增加一条记录,而T_student和T_Course表都不用变更。
// 获取代表Bill的Student对象
        Student stu  =  (Student)session.createQuery( " from Student s where s.name='Bill' " ).uniqueResult();
        Course course 
=  (Course)session.createQuery( " from Course c where c.name='chemistry' " ).uniqueResult();
        
// 设置stu与course的关联关系
        stu.getCourses().add(course);
        course.getStudents().add(stu);
删除关联关系
删除关联关系比较简单,直接调用对象集合的remove()方法删除不要的对象就可。例如:要从学生Bill的选课清单中删除politics和chemistry两门课,程序代码如下:
         // 获取代表Bill的Student对象
        Student stu  =  (Student)session.createQuery( " from Student s where s.name='Bill' " ).uniqueResult();
        Course course1 
=  (Course)session.createQuery( " from Course c where c.name='politics' " ).uniqueResult();
        Course course2 
=  (Course)session.createQuery( " from Course c where c.name='chemistry' " ).uniqueResult();
        stu.getCourse().remove(course1);
// 删除politics课程
        stu.getCourse().remove(course2); // 删除chemistry课程
运行以上程序将从student_course表中删除这两条记录,但T_student和T_course表没有任何变化

你可能感兴趣的:(J2EE,hibernate,数据库,table,insert,encoding,class)