随笔-124  评论-49  文章-56  trackbacks-0
一对多关联映射(one-to-many)
一对多关联映射利用了多对一关联映射原理
  * 多对一关联映射:在多的一端加和一个外键指向一的一端,它维护的关系是多指向一的
  * 一对多关联映射:在一的一端加和一个外键指向多的一端,它维护的关系是一指向多的
也就是说一对多和多对一的映射策略是一样的,只是站的角度不同,一般都作成双项的
------------------------------------------------------------------------------
1 一对多关联映射(单项Classes--->Student)
在一一端维护关系的缺点:
  * 如果将t_student表里的classesid这段设置为非空,则无法保存
  * 因为不在student这一端维护关系,所以student不知道是哪个班的
    所以需要发出多余的update语句来更新关系
<!--
  Classes:                                  Student:
    private int id;                         private int id;
    private String name;             private String name;
    private Set students;//必须用Set
-->
<class name="com.my.hibernate.Student">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
</class>

<class name="Classes">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<set name="students">
            
<key column="classesid"/>
            
<one-to-many class="Student"/>
        
</set>
</class>
public void testSave1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student1
=new Student();
            student1.setName(
"10");
            session.save(student1);
//先进行save操作
            
            Student student2
=new Student();
            student2.setName(
"祖儿");
            session.save(student2);
//先进行save操作
            
            Set students
=new HashSet();
            students.add(student1);
            students.add(student2);
            Classes classes
=new Classes();
            classes.setName(
"尚学堂");
            classes.setStudents(students);
            session.save(classes);
            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testLoad1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Classes classes
=(Classes)session.load(Classes.class3);
            System.out.println(classes.getName());
            Set students
=classes.getStudents();
            
for(Iterator iter=students.iterator();iter.hasNext();){
                Student student
=(Student)iter.next();
                System.out.print(student.getName()
+";");
            }

            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

2 一对多关联映射(双项Classes<--->Student)

一对多双向关联映射:
  * 在一一端的集合上用<key>,在对方表中加入一个外键指向一的一端
  * 在多的一端采用<many-to-one>
注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段错误

如果在一的一端维护一对多关联关系,hibernate会发出多余的update语句,所以我们一般在多的一端来维护关联关系

关于inverse属性:
   inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
   默认inverse为 false,所以我们可以从一的一端和多的一端维护关联关系,
   如果设inverse为true,则我们只能从多的一端来维护关联关系
注意:inverse属性,只影响数据的存储,也就是持久化。

inverse和cascade:
  * inverse是关联关系的控制方向
  * cascade是操作上的连锁反应

<!--
  Classes:                                      Student:
    private int id;                               private int id;
    private String name;                   private String name;
    private Set students;//必须用 Set private Classes classes;
-->
<class name="Classes">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<set name="students" inverse="true" cascade="all">
                //cascade属性:none 不及连 save-update 插入或更新及连 delete删除及连 all
            
<key column="classesid"/>
            
<one-to-many class="Student"/>
        
</set>
</class>

<class name="com.my.hibernate.Student">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<many-to-one name="classes" column="classesid" cascade="save-update"/>
</class>
public void testSave1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
//在多方维护
            Classes classes=new Classes();
            classes.setName(
"北青");
            
//session.save(classes);//加了cascade属性可以不用
            Student student1=new Student();
            student1.setName(
"黄不接10");
            student1.setClasses(classes);
            session.save(student1);
            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testLoad1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
//从多方读取
            Student student=(Student)session.load(Student.class5);
            System.out.println(student.getName());
            System.out.println(student.getClasses().getName());
            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testSave2(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
//在一方维护,自动转向多方
            Classes classes=new Classes();
            classes.setName(
"尚学堂");
            Student student1
=new Student();
            student1.setName(
"10");
            student1.setClasses(classes);
            Student student2
=new Student();
            student2.setName(
"祖儿");
            student2.setClasses(classes);
            Set students
=new HashSet();
            students.add(student1);
            students.add(student2);
            classes.setStudents(students);
    
            session.save(classes);
            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

多对多关联映射(单项User---->Role)
<many-to-many/>标签
<set>标签中加入属性table="t_user_role"创建关联表
<!--
  User:                              Role:
  private int id;                   private int id;
    private String name;     private String name;
    private Set roles;
-->        
<class name="com.my.hibernate.Role">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
</class>

<class name="User">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<set name="roles" table="t_user_role">
            
<key column="userid"/>
            
<many-to-many class="Role" column="roleid"/>
        
</set>
</class>
public void testSave1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            Role role1
=new Role();
            role1.setName(
"1111");
            Role role2
=new Role();
            role2.setName(
"2222");
            Role role3
=new Role();
            role3.setName(
"3333");
            session.save(role1);
            session.save(role2);
            session.save(role3);
            
            User user1
=new User();
            user1.setName(
"user1");
            Set user1Role
=new HashSet();
            user1Role.add(role1);
            user1Role.add(role2);
            user1.setRoles(user1Role);
            
            User user2
=new User();
            user2.setName(
"user2");
            Set user2Role
=new HashSet();
            user2Role.add(role2);
            user2Role.add(role3);
            user2.setRoles(user2Role);
            
            User user3
=new User();
            user3.setName(
"user3");
            Set user3Role
=new HashSet();
            user3Role.add(role2);
            user3Role.add(role3);
            user3Role.add(role1);
            user3.setRoles(user3Role);
            
            session.save(user1);
            session.save(user2);
            session.save(user3);
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

    
    
public void testLoad1(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            User u1
=(User)session.load(User.class1);
            System.out.println(u1.getName());
            
for(Iterator iter=u1.getRoles().iterator();iter.hasNext();){
                System.out.println(((Role)iter.next()).getName());
            }

            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

多对多关联映射(双项User<---->Role)
<many-to-many/>标签
映射方法:
   <set name="users" table="t_user_role" order-by="userid">
    <key column="roleid"/>
    <many-to-many class="com.my.hibernate.User" column="userid"/>
    </set>
table属性值必须和单向关联的table属性值一致
<key>中column属性值要与单向关联中的<many-to-many>标签中的column属性值一致
<many-to-many>中column属性值要与单向关联中的<key>标签中的column属性值一致
<!--
  User:                                  Role:
  private int id;                   private int id;
    private String name;     private String name;
    private Set roles;           private Set users;
-->
    
<class name="com.my.hibernate.Role">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<set name="users" table="t_user_role" order-by="userid">
            
<key column="roleid"/>
            
<many-to-many class="com.my.hibernate.User" column="userid"/>
        
</set>
    
</class>
    
    
<class name="User">
        
<id name="id">
            
<generator class="native"/>
        
</id>
        
<property name="name"/>
        
<set name="roles" table="t_user_role">
            
<key column="userid"/>
            
<many-to-many class="Role" column="roleid"/>
        
</set>
    
</class>
public void testLoad2(){
        Session session
=null;
        
try{
            session
=HibernateUtils.getSession();
            session.beginTransaction();
            
            Role role
=(Role)session.load(Role.class3);
            System.out.println(role.getName());
            
for(Iterator iter=role.getUsers().iterator();iter.hasNext();){
                System.out.println(((User)iter.next()).getName());
            }

            
            session.getTransaction().commit();
        }
catch(Exception e){
            session.getTransaction().rollback();
            e.printStackTrace();
        }
finally{
            HibernateUtils.closeSession(session);
        }

    }

set 不可重复
posted on 2009-11-03 16:04 junly 阅读(644) 评论(0)  编辑  收藏 所属分类: hibernate/orm

只有注册用户登录后才能发表评论。


网站导航: