Hibernate学习笔记:集合映射之映射Map


容器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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值