`

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方法)

 

package com.shop.jn.entity;

import java.io.Serializable;
import java.sql.Date;

/**
 * entity:goods  商品
 * @author huangwei
 *
 */
public class Goods  implements Serializable{
	private static final long serialVersionUID = 586940311263079808L;
	private int id;
	/**
	 * goods name
	 */
	private String name;
	/**
	 * alias of goods
	 */
	private String alias;
	/**
	 * when goods was brought
	 */
	private java.util.Date buyDateTime;
	/**
	 * when this record was modified
	 */
	private Date latestModDateTime;
	/**
	 * the price of goods
	 */
	private double price;
	/**
	 * the detail of the goods
	 */
	private String description;
	/**
	 * the supermarket the goods belong
	 */
	private Supermarket supermarket;
}

package com.shop.jn.entity;

import java.io.Serializable;
import java.util.List;
/**
 * entity:shop   超市
 * @author huangwei
 *
 */
public class Supermarket  implements Serializable{

	private static final long serialVersionUID = 6517742699077464699L;
	private int id;
	/**
	 * the name of the shop
	 */
	private String name;
	private String description;
	private List<Goods> goods;
	/**
	 * the sum of goods 
	 */
	private int goodsAmount;
	}

 hibernate配置文件如下

 

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

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
    <class name="com.shop.jn.entity.Goods" table="t_goods" lazy="true">
        <!--<cache usage="read-write"/>
        --><id name="id" type="int">
            <column name="ID" precision="19" scale="0">
                <comment>主键id</comment>
            </column>
            <generator class="identity"/>
        </id>
         <property name="name">
            <column name="name">
                <comment>商品的名称</comment>
            </column>
        </property>
       
        <property name="alias"  >
            <column name="alias">
            
                <comment>商品的别名</comment>
            </column>
        </property>
       
        <property name="buyDateTime">
            <column name="buyDateTime" >
                <comment>购买时间</comment>
            </column>
        </property>
        <property name="latestModDateTime">
            <column name="latestModDateTime">
                <comment>最后修改时间</comment>
            </column>
        </property>
        <property name="price">
            <column name="price">
                <comment>商品价格</comment>
            </column>
        </property>
        <property name="description">
            <column name="description">
                <comment>商品的具体信息</comment>
            </column>
        </property>
        <!-- fetch=FetchType.EAGER is equal lazy=false -->
       <many-to-one name="supermarket" class="com.shop.jn.entity.Supermarket" lazy="false" cascade="all" insert="true" update="true" >
            <column name="supermarketId"  >
                <comment>商店</comment>
            </column>
            
        </many-to-one>
      
    </class>
</hibernate-mapping>

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

 

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
	<class name="com.shop.jn.entity.Supermarket" table="t_supermarket"
		lazy="true">
		<!--<cache usage="read-write"/> -->
		<id name="id" type="int">
			<column name="ID"><!-- precision="19" scale="0" -->
				<comment>主键id</comment>
			</column>
			<generator class="identity" />
		</id>
		<property name="name">
			<column name="name">
				<comment>商店的名称</comment>
			</column>
		</property>
		<!--<property name="goodsAmount"> <formula>(select count(*) from t_goods 
			g where g.supermarketId=id)</formula> </property> -->
		<property name="description">
			<column name="description">
				<comment>商店的详细信息</comment>
			</column>
		</property>
		<bag name="goods" lazy="false" fetch="subselect" inverse="true">
			<key column="supermarketId"></key>
			<one-to-many class="com.shop.jn.entity.Goods" />
		</bag>


	</class>
</hibernate-mapping>

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

 

bag标签中有如下属性

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

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

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

 

Hibernate: 
    /* criteria query */ select
        this_.ID as ID1_1_0_,
        this_.name as name2_1_0_,
        this_.description as descript3_1_0_ 
    from
        t_supermarket this_
Hibernate: 
    /* load one-to-many com.shop.jn.entity.Supermarket.goods */ select
        goods0_.supermarketId as supermar8_1_1_,
        goods0_.ID as ID1_0_1_,
        goods0_.ID as ID1_0_0_,
        goods0_.name as name2_0_0_,
        goods0_.alias as alias3_0_0_,
        goods0_.buyDateTime as buyDateT4_0_0_,
        goods0_.latestModDateTime as latestMo5_0_0_,
        goods0_.price as price6_0_0_,
        goods0_.description as descript7_0_0_,
        goods0_.supermarketId as supermar8_0_0_ 
    from
        t_goods goods0_ 
    where
        goods0_.supermarketId=?

 

如果我设置lazy为true呢?

 

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

 

10:31:14,097  WARN  - Caught an exception while evaluating expression '0==goods.size' against value stack
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

0
5
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics