`

hibernate基础-映射关系(一对多I多对多).

阅读更多
一对多关联映射(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"color: #0
分享到:
评论

相关推荐

    hibernate总结

    Hibernate映射一对多关系: public class Dept implements java.io.Serializable { // Fields private Integer deptid; private String deptname; private Integer deptnum; private Integer actNum; private ...

    基于Hibernate与Struts框架的数据持久化应用研究

    -./012340 是一个开放源代码的ID Z ?3RR.2;( 对象关系 映射框架),它对B[\A 进行了轻量级的对象封装,使B3P3 程 序员可以方便地使用对象编程思维来操纵数据库。-./012340 的目标是简化开发者通常的数据持久化编程...

    NHibernate中文帮组文档(2008.11月更新)

    18.2. 双向的一对多关系(Bidirectional one-to-many) 18.3. 级联生命周期(Cascading lifecycle) 18.4. 使用级联更新 18.5. 结论 19. 示例:Weblog 应用程序 19.1. 持久化类 19.2. NHibernate 映射 19.3. ...

    spring chm文档

    9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring ...

    Spring中文帮助文档

    9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一...

    Spring API

    9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一种...

    NHibernate参考文档 2.0.0 chm

    18.2. 双向的一对多关系(Bidirectional one-to-many) 18.3. 级联生命周期(Cascading lifecycle) 18.4. 使用级联更新 18.5. 结论 19. 示例:Weblog 应用程序 19.1. 持久化类 19.2. NHibernate 映射 19.3. ...

    Spring 2.0 开发参考手册

    9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring JDBC包结构...

    Hibernate1:实践

    Hibernate1 练习 此存储库包含以下代码的代码业务逻辑: i. 一对一映射 ii. 一对多映射 iii. 多对多映射 iv. 一对一双向

    java开源包10

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    Java常见面试题208道.docx

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

    NHibernate 资料集合

    Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于ADO.Net)进行了非常轻量级的对象封装,使得程序员可以随心所欲的使用对象编程思维来操纵数据库,目前在国内Java开发界已经...

    springmybatis

    如果不一致就会出错,这一章主要在上一讲基于接口编程的基础上完成如下事情: 1. 用 mybatis 查询数据,包括列表 2. 用 mybatis 增加数据 3. 用 mybatis 更新数据. 4. 用 mybatis 删除数据. 查询数据,前面已经讲过...

    java开源包1

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包101

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包11

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包2

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

    java开源包3

    JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...

Global site tag (gtag.js) - Google Analytics