容器Map, List, Set, Bag都不仅可以映射值(String, Integer,FLoat, Double ...)类型, 还可以映射实体(我们自定义的pojo,有实体标记ID)类型.
映射值类型
考虑前面的Product对象,假如每个Product都配有几个图片(这通常是必需的),新建一个表images (product_id, image_name, image_file) , product_id是外键, 和product的id关联。不打算给images表加入主键约束。如果按照one-to-many作一个对多映射,一个Product有多个image,这样做也可以,但是这样做的话需要做更多的工作: 要创建一个pojo Image, 然后要做映射文件,然后还要在Product的映射文件Product.hbm.xml中加入一对多映射.更简单的做法是:给Product加上一个属性images.是一个Map, key对应着image_name, value对应着image_file. 在Product的映射文件中只需要对这个map作一个映射:
view plaincopy to clipboardprint?
public class Product {
private int id;
private String name;
private float price;
private Set orders;
//映射map
private Map images;
// getters and setters ignored
}
public class Product {
private int id;
private String name;
private float price;
private Set orders;
//映射map
private Map images;
// getters and setters ignored
}
在Product.hbm.xml中队images作映射.
view plaincopy to clipboardprint?
<hibernate-mapping>
<class name="model.Product" table="pp" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" not-null="true" />
</property>
<property name="price" type="java.lang.Float">
<column name="price" precision="2" scale="0"/>
</property>
<!-- 多对多的映射中, 中间表table是必须指定的 -->
<set name="orders" table="etl.order_line" cascade="save-update" fetch="join" lazy="false">
<key column="product_id" />
<many-to-many class="model.Order" column="order_id" />
</set>
<map name="images" table="etl.images" cascade="all">
<key column="product_id" />
<index column="image_name" type="java.lang.String" />
<element column="image_file" type="java.lang.String" />
</map>
</class>
</hibernate-mapping>
<!--
create table images(
product_id int,
image_name varchar(20) not null,
image_file varchar(50) not null
)
create table product(
id int primary key,
name varchar(50) not null,
price float
)
create table etl.order_line(
order_id int,
product_id int
)
alter table images add constraint fk_image_product_id foreign key (product_id) references product(id)
alter table order_line add constraint fk_orderline_order_id foreign key (order_id) references order(id)
alter table order_line add constraint fk_orderline_product_id foreign key (product_id) references product(id)
-->
<hibernate-mapping>
<class name="model.Product" table="pp" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" not-null="true" />
</property>
<property name="price" type="java.lang.Float">
<column name="price" precision="2" scale="0"/>
</property>
<!-- 多对多的映射中, 中间表table是必须指定的 -->
<set name="orders" table="etl.order_line" cascade="save-update" fetch="join" lazy="false">
<key column="product_id" />
<many-to-many class="model.Order" column="order_id" />
</set>
<map name="images" table="etl.images" cascade="all">
<key column="product_id" />
<index column="image_name" type="java.lang.String" />
<element column="image_file" type="java.lang.String" />
</map>
</class>
</hibernate-mapping>
<!--
create table images(
product_id int,
image_name varchar(20) not null,
image_file varchar(50) not null
)
create table product(
id int primary key,
name varchar(50) not null,
price float
)
create table etl.order_line(
order_id int,
product_id int
)
alter table images add constraint fk_image_product_id foreign key (product_id) references product(id)
alter table order_line add constraint fk_orderline_order_id foreign key (order_id) references order(id)
alter table order_line add constraint fk_orderline_product_id foreign key (product_id) references product(id)
-->
写ProductDao,进行测试:
view plaincopy to clipboardprint?
ProductDao:
public interface ProductDao {
public List list();
public Product getById(int id);
public void delete(Product p);
public void save(Product p);
}
ProductDao:
public interface ProductDao {
public List list();
public Product getById(int id);
public void delete(Product p);
public void save(Product p);
}
ProductHibernateDao: (带test case)
view plaincopy to clipboardprint?
package dao.hibernate;
import java.util.*;
import java.util.Map.Entry;
import org.hibernate.Transaction;
import dao.ProductDao;
import model.*;
public class ProductHibernateDao extends BaseHibernateDao implements ProductDao {
public List list() {
return getSession().createQuery("from Product").list();
}
public Product getById(int id) {
return (Product) getSession().get(Product.class, id);
}
public void delete(Product p) {
Transaction tx = getSession().beginTransaction();
getSession().delete(p);
tx.commit();
}
public void save(Product p) {
Transaction tx = getSession().beginTransaction();
getSession().saveOrUpdate(p);
tx.commit();
}
//测试用例
public static void main(String[] args) {
ProductDao dao = new ProductHibernateDao();
//测试查询
List<Product> list = dao.list();
System.out.println(list.size());
for(Product p1 : list){
System.out.println(p1);
Iterator imgItr = p1.getImages().entrySet().iterator();
while(imgItr.hasNext()){
Entry e = (Entry)imgItr.next();
System.out.println(e.getKey() + " ### " + e.getValue());
}
}
//测试添加
Product p = dao.getById(7);
Map map = new HashMap();
map.put("tea1", "tea1.jpg");
map.put("tea2", "tea2.jpg");
map.put("tea3", "tea3.jpg");
map.put("tea4", "tea4.jpg");
p.setImages(map);
dao.save(p);
//测试删除
Product p2 = dao.getById(4);
p2.setImages(null);
dao.save(p2);
}
}
package dao.hibernate;
import java.util.*;
import java.util.Map.Entry;
import org.hibernate.Transaction;
import dao.ProductDao;
import model.*;
public class ProductHibernateDao extends BaseHibernateDao implements ProductDao {
public List list() {
return getSession().createQuery("from Product").list();
}
public Product getById(int id) {
return (Product) getSession().get(Product.class, id);
}
public void delete(Product p) {
Transaction tx = getSession().beginTransaction();
getSession().delete(p);
tx.commit();
}
public void save(Product p) {
Transaction tx = getSession().beginTransaction();
getSession().saveOrUpdate(p);
tx.commit();
}
//测试用例
public static void main(String[] args) {
ProductDao dao = new ProductHibernateDao();
//测试查询
List<Product> list = dao.list();
System.out.println(list.size());
for(Product p1 : list){
System.out.println(p1);
Iterator imgItr = p1.getImages().entrySet().iterator();
while(imgItr.hasNext()){
Entry e = (Entry)imgItr.next();
System.out.println(e.getKey() + " ### " + e.getValue());
}
}
//测试添加
Product p = dao.getById(7);
Map map = new HashMap();
map.put("tea1", "tea1.jpg");
map.put("tea2", "tea2.jpg");
map.put("tea3", "tea3.jpg");
map.put("tea4", "tea4.jpg");
p.setImages(map);
dao.save(p);
//测试删除
Product p2 = dao.getById(4);
p2.setImages(null);
dao.save(p2);
}
}
映射实体类型
上面采用值类型映射,是因为需要映射的字段就2个, 但是如果多于2个的话就不得不在Map里面放实体.为了放实体, 就需要有pojo Image, 它必须有id, 还要有映射文件.为了不更改表结构, 我们新建一个用来映射Image的表images1.
view plaincopy to clipboardprint?
package model;
public class Image {
private int id;
private String imageName;
private String imageFile;
public String toString(){
return "/nid: " + id + "/nimageName: " + imageName + "/nimageFile: " + imageFile;
}
//getters and setters ignored
}
package model;
public class Image {
private int id;
private String imageName;
private String imageFile;
public String toString(){
return "/nid: " + id + "/nimageName: " + imageName + "/nimageFile: " + imageFile;
}
//getters and setters ignored
}
Image.hbm.xml
view plaincopy to clipboardprint?
<hibernate-mapping package="model">
<class name="Image" table="images1" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="imageName" column="image_name" length="20" />
<property name="imageFile" column="image_File" length="50" />
</class>
</hibernate-mapping>
<!--
create table images1(
id int primary key identity(1,1),
product_id int,
image_name varchar(20) not null,
image_file varchar(50) not null
)
alter table images1 add constraint fk_images1_product_id
foreign key (product_id) references product(id)
insert into images1(product_id, image_name, image_file) values(5, 'prod32', 'prod32.jpg')
-->
<hibernate-mapping package="model">
<class name="Image" table="images1" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="imageName" column="image_name" length="20" />
<property name="imageFile" column="image_File" length="50" />
</class>
</hibernate-mapping>
<!--
create table images1(
id int primary key identity(1,1),
product_id int,
image_name varchar(20) not null,
image_file varchar(50) not null
)
alter table images1 add constraint fk_images1_product_id
foreign key (product_id) references product(id)
insert into images1(product_id, image_name, image_file) values(5, 'prod32', 'prod32.jpg')
-->
修改一下Product.hbm.xml:
view plaincopy to clipboardprint?
<hibernate-mapping>
<class name="model.Product" table="pp" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" not-null="true" />
</property>
<property name="price" type="java.lang.Float">
<column name="price" precision="2" scale="0"/>
</property>
<set name="orders" table="etl.order_line" cascade="save-update" fetch="join" lazy="false">
<key column="product_id" />
<many-to-many class="model.Order" column="order_id" />
</set>
<!--map中映射实体-->
<map name="images" cascade="all">
<key column="product_id" />
<index column="image_name" type="java.lang.String" />
<one-to-many class="model.Image" />
</map>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="model.Product" table="pp" schema="etl" catalog="gssg_crms">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" not-null="true" />
</property>
<property name="price" type="java.lang.Float">
<column name="price" precision="2" scale="0"/>
</property>
<set name="orders" table="etl.order_line" cascade="save-update" fetch="join" lazy="false">
<key column="product_id" />
<many-to-many class="model.Order" column="order_id" />
</set>
<!--map中映射实体-->
<map name="images" cascade="all">
<key column="product_id" />
<index column="image_name" type="java.lang.String" />
<one-to-many class="model.Image" />
</map>
</class>
</hibernate-mapping>
修改ProductHibernateDao的测试用例:
view plaincopy to clipboardprint?
public static void main(String[] args) {
ProductDao dao = new ProductHibernateDao();
List<Product> list = dao.list();
System.out.println(list.size());
for(Product p1 : list){
System.out.println(p1);
Map<String, Image> map = p1.getImages();
Iterator itr = map.entrySet().iterator();
if(map!=null&&map.size()!=0){
System.out.println("############### images for this product ###############");
}
while(itr.hasNext()){
Entry e = (Entry) itr.next();
System.out.println(e.getValue());
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sunxing007/archive/2009/08/24/4479060.aspx