项目名称: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