一对多关联映射(单向)

“一对多”,顾名思义,是由“一”的一端加载“多”的一端,关系交由“一”来维护。反映在Java代码中就是在“一”的一端中持有“多”一端的集合,而hibernate把这种关系反映到数据库的策略是在“多”一端的表上加上一个外键指向“一”一端表。显现,其实这采用的还是“多対一”的映射原理。
     但是,在“一”一端维护关系是我们不提倡的,因为它有不可避免的缺点,即级联插入数据的时候要先插“多”一端,这样造成了两方面的不妥:1.如果我们把“多”一端的外键必须添加非空约束,将导致数据不能插入;2.即使外键不设置为非空,在插入“多”一端数据时外键将暂时为空( 因为此时它所引用的“一”记录还没有插入),而只有等到它所引用的“一”记录插入后,再发出update语句修改外键,这样的效率必然降低。
     不管怎样,还是来看看我的Classes和Student怎么做的吧。
1.实体模型:


 
 
2.关系模型:


 
 
3.实体类:
    Student.java
public   class  Student {  
   private  Integer id;  
   private  String name;  
   //一系列的setter.getter方法 
  @Override  
   public  String toString() {  
     return   "name of student: "  + name;  
  }  
}
   Classes.java
public   class  Classes {  
   private  Integer id;  
   private  String name;  
   private  Set<Student> students;  
   //一系列的setter.getter方法 
  @Override  
   public  String toString() {  
     return   "name of class: "  + name;  
  }  
}
 
4.映射文件
   Student.hbm.xml
   < class   name ="com.sxt.hibernate.one2many.entity.Student"   table ="sxt_hibernate_student" >  
     < id   name ="id"   length ="4" >  
       < generator   class ="native" > </ generator >  
     </ id >  
     < property   name ="name"   length ="10" > </ property >  
   </ class >
   Classes.hbm.xml
   < class   name ="com.sxt.hibernate.one2many.entity.Classes"   table ="sxt_hibernate_class" >  
     < id   name ="id"   length ="4" >  
       < generator   class ="native" > </ generator >  
     </ id >  
     < property   name ="name"   length ="10" > </ property >  
    <!--  配置集合属性 -->  
     < set   name ="students"   cascade ="save-update" >  
      <!--  key的含义,指在另一端增加的外键指向本主键. 
        如果设置上属性not-null="true",表示该外键非空,则在由"一"的一端维护关系时, 
        可能导致插入数据异常PropertyValueException. 
        
-->  
       < key   column ="class_id" > </ key >  
      <!-- one-to-many含义,指出set集合中的元素类型,以供加载时使用    -->  
       < one-to-many   class ="com.sxt.hibernate.one2many.entity.Student" />  
     </ set >  
   </ class >
 
5.hibernate配置文件:
   参考前面的。
 
6.测试方法:
   public   static   void  main(String[] args) {  
    Session session = HibernateUtils.getSession();  
    Transaction t = session.beginTransaction();  
     try  {  
       /** 
        * 测试插入数据 
        */
 
       /* 
        * Student student1=new Student();    
        * student1.setName("奇隆"); 
        *    
        * Student student2=new Student();    
        * student2.setName("有朋"); 
        *    
        * Set<Student> students=new HashSet<Student>(); 
        * students.add(student1);    
        * students.add(student2); 
        *    
        * Classes classes=new Classes();    
        * classes.setName("不一班"); 
        * classes.setStudents(students); 
        * //存储不成功.报错:org.hibernate.TransientObjectException 
        * //因为此时student对象还没有持久化,classes引用了瞬时对象student1,student2 
        * session.save(classes); 
        */
 

        
        Student student1= new  Student(); student1.setName( "奇隆");  
         //session.save(student1);//先把student对象持久化 
          
        Student student2= new  Student();  
        student2.setName( "有朋");    
         //session.save(student2); 
          
        Set<Student> students= new  HashSet<Student>();  
        students.add(student1);  
        students.add(student2);  
          
        Classes classes= new  Classes();  
        classes.setName( "不一班");  
        classes.setStudents(students);  
         //存储成功.sql语句如下: 
         /* 
        Hibernate: insert into sxt_hibernate_class (name, id) values (?, ?) 
        Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?) 
        Hibernate: insert into sxt_hibernate_student (name, id) values (?, ?) 
        Hibernate: update sxt_hibernate_student set class_id=? where id=? 
        Hibernate: update sxt_hibernate_student set class_id=? where id=? */
 
         //可见在存储class之后,发出两个update语句,把它的两个student对象的class_id更新了. 
         //这是因为关系由"一"的一端维护(即class维护关系).这显然会降低效率. 
         //所以对于一对多,我们一般把关系交给"多"的一端维护.    
        session.save(classes);  
          
       /** 
        * 测试加载数据 
        */
 
/*      Classes classes = (Classes) session.load(Classes.class, 3); 
      System.out.println(classes); 
      Set<Student> students = classes.getStudents(); 
      for (Iterator<Student> stus = students.iterator(); stus.hasNext();) { 
        System.out.println(stus.next()); 
      }*/
 
      t.commit();  
    }   catch  (HibernateException e) {  
      e.printStackTrace();  
      t.rollback();  
    }   finally  {  
      HibernateUtils.closeSession(session);  
    }  
  }  

}  

本文出自 “夜狼” 博客,请务必保留此出处http://yangfei520.blog.51cto.com/1041581/275656

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis是一款优秀的ORM框架,支持一对一、一对多、多对一、多对多等关联映射。其中,一对多关联映射是指一个实体类中包含多个另一个实体类的对象。下面是一对多关联映射实现方法: 1.在主实体类中定义一个包含从实体类对象的List集合属性。 2.在主实体类对应的Mapper.xml文件中,使用<collection>标签来映射从实体类对象的List集合属性。 3.在从实体类对应的Mapper.xml文件中,使用<association>标签来映射主实体类对象。 具体实现可以参考以下代码: 主实体类User: ``` public class User { private Integer id; private String username; private List<Order> orders; //getter和setter方法 } ``` 从实体类Order: ``` public class Order { private Integer id; private String orderNo; private User user; //getter和setter方法 } ``` 主实体类User对应的Mapper.xml文件: ``` <mapper namespace="com.biem.mapper.UsersMapper"> <resultMap id="userMap" type="User"> <id property="id" column="id"/> <result property="username" column="username"/> <collection property="orders" ofType="Order"> <id property="id" column="order_id"/> <result property="orderNo" column="order_no"/> </collection> </resultMap> <select id="getUserById" resultMap="userMap"> select * from user where id=#{id} </select> </mapper> ``` 从实体类Order对应的Mapper.xml文件: ``` <mapper namespace="com.biem.mapper.OrdersMapper"> <resultMap id="orderMap" type="Order"> <id property="id" column="id"/> <result property="orderNo" column="order_no"/> <association property="user" javaType="User"> <id property="id" column="user_id"/> <result property="username" column="username"/> </association> </resultMap> <select id="getOrderById" resultMap="orderMap"> select * from order where id=#{id} </select> </mapper> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值