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

相关文章
|
4月前
|
Java 数据库连接 API
解锁高效开发秘籍:深入探究 Hibernate 如何优雅处理一对多与多对多关系,让数据映射再无烦恼!
【9月更文挑战第3天】Hibernate 是 Java 领域中最流行的 ORM 框架之一,广泛用于处理实体对象与数据库表之间的映射。尤其在处理复杂关系如一对多和多对多时,Hibernate 提供了丰富的 API 和配置选项。本文通过具体代码示例,展示如何使用 `@OneToMany`、`@JoinColumn`、`@ManyToMany` 和 `@JoinTable` 等注解优雅地实现这些关系,帮助开发者保持代码简洁的同时确保数据一致性。
74 4
|
5月前
|
Java 数据库连接 数据库
AI 时代风起云涌,Hibernate 实体映射引领数据库高效之路,最佳实践与陷阱全解析!
【8月更文挑战第31天】Hibernate 是一款强大的 Java 持久化框架,可将 Java 对象映射到关系数据库表中。本文通过代码示例详细介绍了 Hibernate 实体映射的最佳实践,包括合理使用关联映射(如 `@OneToMany` 和 `@ManyToOne`)以及正确处理继承关系(如单表继承)。此外,还探讨了常见陷阱,例如循环依赖可能导致的无限递归问题,并提供了使用 `@JsonIgnore` 等注解来避免此类问题的方法。通过遵循这些最佳实践,可以显著提升开发效率和数据库操作性能。
100 0
|
5月前
|
数据库 开发者 Java
Hibernate映射注解的魔力:实体类配置的革命,让你的代码量瞬间蒸发!
【8月更文挑战第31天】Hibernate 是一款出色的对象关系映射框架,简化了 Java 应用与数据库的交互。其映射注解让实体类配置变得直观简洁。本文深入剖析核心概念与使用技巧,通过示例展示如何简化配置。
64 0
|
SQL XML 存储
Hibernate框架【五】——基本映射——多对多映射
Hibernate框架【五】——基本映射——多对多映射
211 0
|
8月前
|
缓存 Java 数据库连接
Hibernate或MyBatis:ORM映射、缓存机制等知识讲解梳理
Hibernate或MyBatis:ORM映射、缓存机制等知识讲解梳理
140 0
|
8月前
|
Java 数据库连接 数据库
Hibernate5中实体映射命名策略
Hibernate5中实体映射命名策略
152 0
|
8月前
|
SQL 存储 Java
Hibernate - 继承关联关系映射
Hibernate - 继承关联关系映射
78 0
|
8月前
|
SQL Java 关系型数据库
Hibernate - Java 类型, Hibernate 映射类型及 SQL 类型之间的对应关系
Hibernate - Java 类型, Hibernate 映射类型及 SQL 类型之间的对应关系
84 0
|
SQL XML Java
Hibernate框架【四】——基本映射——多对一和一对多映射
Hibernate框架【四】——基本映射——多对一和一对多映射
193 0
|
XML 存储 Java
Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【三】——基本映射——一对一映射
92 0