項目名稱:shop_goods
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;
}
import java.util.list;
* entity:shop 超市
public class supermarket implements serializable{
private static final long serialversionuid = 6517742699077464699l;
* the name of the shop
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>
</property>
<property name="alias" >
<column name="alias">
<comment>商品的别名</comment>
<property name="buydatetime">
<column name="buydatetime" >
<comment>購買時間</comment>
<property name="latestmoddatetime">
<column name="latestmoddatetime">
<comment>最後修改時間</comment>
<property name="price">
<column name="price">
<comment>商品價格</comment>
<property name="description">
<column name="description">
<comment>商品的具體資訊</comment>
<!-- 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>
</many-to-one>
</class>
</hibernate-mapping>
supermarket.hbm.xml(一的一方):

<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" -->
<generator class="identity" />
<property name="name">
<comment>商店的名稱</comment>
<!--<property name="goodsamount"> <formula>(select count(*) from t_goods
g where g.supermarketid=id)</formula> </property> -->
<comment>商店的詳細資訊</comment>
<bag name="goods" lazy="false" fetch="subselect" inverse="true">
<key column="supermarketid"></key>
<one-to-many class="com.shop.jn.entity.goods" />
</bag>
主要對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_
/* 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_
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