关于hibernate的onetomany和manytomany

来源:互联网 发布:监控qq软件 编辑:程序博客网 时间:2024/05/02 01:12

 1.one to many
 
  (1)对于1这一方的操作与多的一方级联级
 增加1时  可以普通的双增,也就是先new一的一方,在new多的一方的多个,把一的外键给多的几个实体,分别save一和多 
 要点  new了几个实体就要save几次
 例如:
  Dept dept=new Dept();
         dept.setD_name("就业");
        
         Ren ren=new Ren();
         ren.setR_name("小明");
         Ren ren1=new Ren();
         ren1.setR_name("小王");
        
         ren.setDept(dept);
         ren1.setDept(dept);
        
         session.save(dept);
         session.save(ren);
         session.save(ren1); 
 
 增加1时  可以级联增加 
 要点  把多的一方new出来后,放到一的一方的set里,最后只save一的一方,并且只保存一次
 例如:
  Dept dept=new Dept();
  dept.setD_name("就业2");

         Ren ren=new Ren();
         ren.setR_name("小明1");
         Ren ren1=new Ren();
         ren1.setR_name("小王1");
        
         dept.getRenSet().add(ren);
         dept.getRenSet().add(ren1);
         session.save(dept);

--------------------------------增加修改和删除时与cascade=all有关:如果没有级联 只有为null一种情况!------------------------


 删除一的时候   如果new  从表与之关联外键变null
 例如:
  Dept dept=new Dept();
  dept.setD_id("4028803b223f64ad01223f64e4f00001");
  session.delete(dept);
  
 删除一的时候   先查出来load  全删除(主从)
 例如:
  session.delete(session.load(Dept.class, "4028803b223f629a01223f62d1520001"));


 修改一的时候   如果new  从表与之关联外键变null
 例如:
  Dept dept=new Dept();
  dept.setD_id("4028803b223f64ad01223f64e4f00001");
  dept.setD_name("就业5");
  session.update(dept);
  
 修改一的时候   先查出来load  从表与之关联外键不变
 例如:
  Dept dept=(Dept)session.load(Dept.class, "4028803b230c3f0501230c3f08120001");
  dept.setD_name("就业5");
  session.update(dept);
 
 问题:如何通过一的一方修改多的一方中的一条?
 要点:本质上说hibernate的关系都存在set中,那么无论什么操作都可以通过set来级联的
      本问题就是一例,如果修改中间表的一条,那么只需要把一的一方的set中的要修改的一条,查出来再修改最后updata一就可以了

      相似的情况,如果要加一条,就在一的一方的set中加一条,最后update就可以了
      记住,当要增加多的一方时,相当于对一的一方进行修改了

      相似的情况,如果要修改一条,删除只能把关系删除,不能把多的一方删除,多的一方外变null


      两种极限情况是:只修改一的一方
       不修改一的一方,对多的一方即有添加又有修改还有删除,但是删除只能把关系删除,不能把多的一方删除,多的            一方外键变null

      最复杂的请是:修改一的一方,多的一方即添加又有修改还有删除

 例如:
  Dept dept=(Dept)session.load(Dept.class, "4028803b230c3f0501230c3f08120001");
  dept.setD_name("就业5");

         Ren ren1=new Ren();
         ren1.setR_name("小王5");
        
         Iterator it=dept.getRenSet().iterator();
         while(it.hasNext())
         {
          Ren r=(Ren)it.next();
          if(r.getR_id().equals("4028803b230c3f0501230c3f08310002"))
          {
           it.remove();
          }
         }
         dept.getRenSet().add(ren1);
         session.update(dept); 

  (2)对于多的这一方的操作
 概述:只要不涉及到外键的操作,就是单表的操作
 
 增: 给外键的实体类,正常增
 删: 正常删
 改: 不改外键时,正常改
     改外键时,new外键实体,给外键实体赋id,传给多的这一方的实体,在改
 
 
  (3)关于onetomany实体配置的注意事项
 一对多:埋实体不能new  埋set要new

 

2.manytomany
 
  manytomany有两种配法: manytomany
   两个onetomany

  (1)manytomany
 概述:
  中间表没有表的实体类和配置文件
  中间表仅有两个字段,分别是两边表的各自主键
  两边表配置的时候,互相埋一个set来装对方实体
  两边表可以操作中间表
  中间没有单独的操作,只能被两边表的对set操作来操作
 

 配置:两边表互相埋一个set来装对方实体
 例如: 


  Teacher实体类

  private String tid;
  private String name;
  private Set courseSet = new HashSet();

 

  Teacher配置文件
  
  <id name="tid" column="tid">
              <generator class="uuid.hex"/>   
  </id>
  
  <property name="name" column="name" type="string"  length="50" not-null="false" />
  
  <set name="courseSet" table="mid">
   <key column="tid" />
   <many-to-many class="middle.entity.Course" column="cid"/>
  </set>

--------------------------------------------------
  
  Course类  

  
  private String cid;
  private String cname;
  private Set teacherSet = new HashSet();
  

  Course配置文件

  <id name="cid" column="cid">
              <generator class="uuid.hex"/>   
  </id>
  
  <property name="cname" column="cname" type="string"  length="50" not-null="false" />
  
  <set name="teacherSet" table="mid">
   <key column="cid" />
   <many-to-many class="middle.entity.Teacher" column="tid"/>
  </set>

 


 增:类似一对多,在任意一边的表中的set里装另一方最后在Save就可以了
 例如:
  public void saveTeacher_kc(Teacher t,String []kc){
   for (int i = 0; i < kc.length; i++) {
    Course c = new Course();
    c.setCid(kc[i]);
    t.getCourseSet().add(c);
   }
   dao.save(t);
  }
 

 删除:由于两边表可以操作中间表,所以删除两边表的一方,中间表与之对应的就都删除了
  public void deleteTeacher_kc(String ids[]){
   for (int i = 0; i < ids.length; i++) {
    Teacher t1 = (Teacher)dao.queryById(ids[i]);
    dao.delete(t1);
   }
  }

 修改:本质--set里有什么,中间表里就有什么
      技巧--一般来说,先要把中间表中已有的记录都清除,在一次性的重新给值,这样便于操作
      具体实现--把某一方的set给clear()了,在给set执行add()添加一些新的记录,最后update
 例如:
  public void editTeacher_kc(String id ,String name , String []kc){
   Teacher teacher = (Teacher)dao.queryById(id);
   teacher.getCourseSet().clear();
   teacher.setName(name);
   if(kc!=null){
    for (int i = 0; i < kc.length; i++) {
     Course course = new Course();
     course.setCid(kc[i]);
     teacher.getCourseSet().add(course);
    }
   }
  }
 
  (2)两个onetomany
 概述:本质上就是一对多,所有的操作就是一对多
      配置时,中间有自己的表实体和配置文件
      中间表中除了有两边表的外间外,还可以有自己的主键和自己的字段
     

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

原创粉丝点击