hibernate 映射-一对多双向

项目名称:shop_goods

使用spring ,hibernate,struts2,分别的版本如下:

spring :3.2.3.RELEASE

hibernate:4.2.2.Final

struts2:2.3.4.1

使用xml配置,使用maven构建。

这里涉及两个实体类:商品,超市。因为要讲解一对多的关系映射,所以假设商品和超市之间是多对一联系。

一个超市有多个商品,一个商品只属于一个超市。

实体类代码如下(省略setter,getter方法)

 

Java代码  

  1. package com.shop.jn.entity;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.Date;  
  5.   
  6. /** 
  7.  * entity:goods  商品 
  8.  * @author huangwei 
  9.  * 
  10.  */  
  11. public class Goods  implements Serializable{  
  12.     private static final long serialVersionUID = 586940311263079808L;  
  13.     private int id;  
  14.     /** 
  15.      * goods name 
  16.      */  
  17.     private String name;  
  18.     /** 
  19.      * alias of goods 
  20.      */  
  21.     private String alias;  
  22.     /** 
  23.      * when goods was brought 
  24.      */  
  25.     private java.util.Date buyDateTime;  
  26.     /** 
  27.      * when this record was modified 
  28.      */  
  29.     private Date latestModDateTime;  
  30.     /** 
  31.      * the price of goods 
  32.      */  
  33.     private double price;  
  34.     /** 
  35.      * the detail of the goods 
  36.      */  
  37.     private String description;  
  38.     /** 
  39.      * the supermarket the goods belong 
  40.      */  
  41.     private Supermarket supermarket;  
  42. }  
  43.   
  44. package com.shop.jn.entity;  
  45.   
  46. import java.io.Serializable;  
  47. import java.util.List;  
  48. /** 
  49.  * entity:shop   超市 
  50.  * @author huangwei 
  51.  * 
  52.  */  
  53. public class Supermarket  implements Serializable{  
  54.   
  55.     private static final long serialVersionUID = 6517742699077464699L;  
  56.     private int id;  
  57.     /** 
  58.      * the name of the shop 
  59.      */  
  60.     private String name;  
  61.     private String description;  
  62.     private List<Goods> goods;  
  63.     /** 
  64.      * the sum of goods  
  65.      */  
  66.     private int goodsAmount;  
  67.     }  

 hibernate配置文件如下

 

Goods.hbm.xml(多的一方):

 

Xml代码  

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  3.   
  4. <hibernate-mapping>  
  5.     <class name="com.shop.jn.entity.Goods" table="t_goods" lazy="true">  
  6.         <!--<cache usage="read-write"/> 
  7.         --><id name="id" type="int">  
  8.             <column name="ID" precision="19" scale="0">  
  9.                 <comment>主键id</comment>  
  10.             </column>  
  11.             <generator class="identity"/>  
  12.         </id>  
  13.          <property name="name">  
  14.             <column name="name">  
  15.                 <comment>商品的名称</comment>  
  16.             </column>  
  17.         </property>  
  18.          
  19.         <property name="alias"  >  
  20.             <column name="alias">  
  21.               
  22.                 <comment>商品的别名</comment>  
  23.             </column>  
  24.         </property>  
  25.          
  26.         <property name="buyDateTime">  
  27.             <column name="buyDateTime" >  
  28.                 <comment>购买时间</comment>  
  29.             </column>  
  30.         </property>  
  31.         <property name="latestModDateTime">  
  32.             <column name="latestModDateTime">  
  33.                 <comment>最后修改时间</comment>  
  34.             </column>  
  35.         </property>  
  36.         <property name="price">  
  37.             <column name="price">  
  38.                 <comment>商品价格</comment>  
  39.             </column>  
  40.         </property>  
  41.         <property name="description">  
  42.             <column name="description">  
  43.                 <comment>商品的具体信息</comment>  
  44.             </column>  
  45.         </property>  
  46.         <!-- fetch=FetchType.EAGER is equal lazy=false -->  
  47.        <many-to-one name="supermarket" class="com.shop.jn.entity.Supermarket" lazy="false" cascade="all" insert="true" update="true" >  
  48.             <column name="supermarketId"  >  
  49.                 <comment>商店</comment>  
  50.             </column>  
  51.               
  52.         </many-to-one>  
  53.         
  54.     </class>  
  55. </hibernate-mapping>  

 Supermarket.hbm.xml(一的一方):

 

 

Xml代码  

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
  3.   
  4. <hibernate-mapping>  
  5.     <class name="com.shop.jn.entity.Supermarket" table="t_supermarket"  
  6.         lazy="true">  
  7.         <!--<cache usage="read-write"/> -->  
  8.         <id name="id" type="int">  
  9.             <column name="ID"><!-- precision="19" scale="0" -->  
  10.                 <comment>主键id</comment>  
  11.             </column>  
  12.             <generator class="identity" />  
  13.         </id>  
  14.         <property name="name">  
  15.             <column name="name">  
  16.                 <comment>商店的名称</comment>  
  17.             </column>  
  18.         </property>  
  19.         <!--<property name="goodsAmount"> <formula>(select count(*) from t_goods   
  20.             g where g.supermarketId=id)</formula> </property> -->  
  21.         <property name="description">  
  22.             <column name="description">  
  23.                 <comment>商店的详细信息</comment>  
  24.             </column>  
  25.         </property>  
  26.         <bag name="goods" lazy="false" fetch="subselect" inverse="true">  
  27.             <key column="supermarketId"></key>  
  28.             <one-to-many class="com.shop.jn.entity.Goods" />  
  29.         </bag>  
  30.   
  31.   
  32.     </class>  
  33. </hibernate-mapping>  

 主要对bag标签进行详细的说明

 

bag标签中有如下属性

lazy(可选--默认为 true)可以用来关闭延迟加载(false)

如果指定lazy为false,则在查询supermarket(一的一方)时会把supermarket中的goods(多的一方)也查询出来,查询的的策略有三种:subselect,select,join

这里使用的策略是fetch属性指定的subselect,执行的SQL语句如下:

 

Sql代码  

  1. Hibernate:   
  2.     /* criteria query */ select  
  3.         this_.ID as ID1_1_0_,  
  4.         this_.name as name2_1_0_,  
  5.         this_.description as descript3_1_0_   
  6.     from  
  7.         t_supermarket this_  
  8. Hibernate:   
  9.     /* load one-to-many com.shop.jn.entity.Supermarket.goods */ select  
  10.         goods0_.supermarketId as supermar8_1_1_,  
  11.         goods0_.ID as ID1_0_1_,  
  12.         goods0_.ID as ID1_0_0_,  
  13.         goods0_.name as name2_0_0_,  
  14.         goods0_.alias as alias3_0_0_,  
  15.         goods0_.buyDateTime as buyDateT4_0_0_,  
  16.         goods0_.latestModDateTime as latestMo5_0_0_,  
  17.         goods0_.price as price6_0_0_,  
  18.         goods0_.description as descript7_0_0_,  
  19.         goods0_.supermarketId as supermar8_0_0_   
  20.     from  
  21.         t_goods goods0_   
  22.     where  
  23.         goods0_.supermarketId=?  

 

如果我设置lazy为true呢?

 

调用supermarket.getGoods().size()时就会报错:

 

Xml代码  

  1. 10:31:14,097  WARN  - Caught an exception while evaluating expression '0==goods.size' against value stack  
  2. org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.shop.jn.entity.Supermarket.goods, could not initialize proxy - no Session  

 因为使用的是懒加载,查询supermarket时没有把goods查询出来。

 

 

inverse(可选 — 默认为 false)标记这个集合作为双向关联关系中的方向一端。因为这里是双向关联,所以设置inverse为true

时间: 2025-01-30 00:05:01

hibernate 映射-一对多双向的相关文章

【SSH系列】Hibernate映射 -- 一对多关联映射

     映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一

hibernate 映射-多对多双向

hibernate 中的多对多,在数据库中就是一张中间表, 范例: 考试与考试之间是一种多对多的关系: (1)一个考生可以参加多场考试: (2)一场考试可以有多个考生参加: (3)不同的考生可以参加同一场考试:不同的考试可以有相同的考生. 考生类:User,中有成员变量private List<Exam> exams  考试类:Exam,中有成员变量 private List<User> users 在User.Java 中的配置: Java代码   @ManyToMany    

Hibernate从入门到精通(九)一对多双向关联映射

上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在一的一端存在多的一端的一个集合对象,在多的一端存在一的一端的一个对象,这样就可以保证在加 载一的一端或多的一端将被指向端的集合或对象加载上来,即保证双向关联. 一对多双向关联映射和 一对多单向关联映射的异同 一对多双向关联映射相应的类结构图和代码.具体如下: public class Classes

【SSH系列】hibernate映射 -- 一对一双向关联映射

       开篇前言       上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.为什么呢,因为对象模型具有方向性,在前面的博文Hibernate基本映射中,小编介绍了单向和双向,所谓的单向就是一段只能加载另一个端,不能反过来:双向就是两端都可以加载另一端,可以这样来理解,单向就是一厢情愿,双向就是两情相悦.ok,那么问题来了,如果我

hibernate级联删除时无法删除,一对多双向关联,一是Consult 多是TbFiles

问题描述 hibernate级联删除时无法删除,一对多双向关联,一是Consult 多是TbFiles 一的配置: 多的配置: class="com.project.dto.Consult" fetch="select" cascade="all"> 执行代码: public void delConsult(String[] ids){ HibernateTemplate hTemplate=this.getHibernateTemplat

【SSH系列】Hibernate映射 -- 一对一单向关联映射

       映射原理       一对一关联映射:两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应.有两种策略可以实现一对一的关联映射:       a.主键关联:即让两个对象具有相同的主键值,以表明她们之间的一一对应的关系:数据库表不会有额外的字段来维护她们之间的关系,仅通过表的主键来关联.       b.唯一外键关联:外键关联,本来适用于多对一的配置,但是如果加上唯一的限制之后,也可以表示一对一关联关系,谈恋爱就是一一对应,一个男朋友对应一个女朋友,如果不是,

Java的Hibernate框架中的双向主键关联与双向外键关联_java

一.双向主键关联双向的主键关联其实是单向一对一主键关联的一种特殊情况,只不过要在关联对象的两端的映射文件中都要进行<one-to-one>的配置,另外还要在主映射的主键一端采用foreign外键关联属性. 这里同样使用Person和IdCard来讨论,一个人对应着一个唯一的身份证,而且一个身份证也唯一映射着一个人,所以这就产生了双向的关联关系,Person的主键同样也是IdCard的主键,分别是主键的同时也是外键,这种关联关系成为双向一对一映射,表现到关系模型中可如下图: 图中的两个表采用了主

关于hibernate单向一对多的一个问题

问题描述 关于hibernate单向一对多的一个问题 一个学生一个班级,班级一对多学生,班级中有一个Set里面存放学生,我执行下面的代码 @Test public void testUpdateStuToNewClass(){ Session session = factory.openSession(); Transaction transaction = session.beginTransaction(); Student stu = session.get(Student.class,

Hibernate映射与注解实例总结

  XML配置 1.一对一单向 <class name="Person">      <id name="id" column="personId">          <generator class="native"/>      </id>      <many-to-one name="address"         column="