您的位置:首页 > 其它

Hibernate高级映射 --- 组件映射

2011-12-12 17:51 302 查看
Hibernate高级映射 --- 组件映射
一  概念

1.组件映射概念

    Hibernate建议在进行领域模型建模时要细粒度一些,简单的说,就是类要比表多,这种映射就是组件映射

    组件类是值类型的,即它没有对象标识符属性,在数据库中也没有对应的表,它只隶书于另一个持久化类的实例。它的数据被嵌入到所隶书的持久化实例对应的数据库表的记录中。

2.组件映射的应用有三种常见的情况:

(1)把组件类作为持久化类的单个属性来使用

(2)把组件类作为持久化类的集合属性来使用

(3)把组件类作为持久化类的对象标识符来使用

3.组件类的作用

如果在User的实体类中有一个Name实体类,如果要想把Name的实体类放到User的表中,成为一张表,要用到组件映射。

二  代码分析  以User和Name为例

第一种:把组件类作为持久化类的单个属性来使用

1.建Name表  用来设置Name类中的属性

package com.hbsi.domain;
public class Name {
    private String firstName;
    private String lastName;
    public String getFirstName() {
       return firstName;
    }
    public void setFirstName(String firstName) {
       this.firstName = firstName;
    }
    public String getLastName() {
       return lastName;
    }
    public void setLastName(String lastName) {
       this.lastName = lastName;
    }
}
2.建User表

package com.hbsi.domain;
import java.util.Date;
public class User {
    private int id;
    private Name name;//实体类
    private Date birthday;
    public User() {
       super();
       // TODO Auto-generatedconstructor stub
    }
    public User(int id, Namename, Date birthday) {
       super();
       this.id = id;
       this.name = name;
       this.birthday = birthday;
    }
    public int getId() {
       return id;
    }
    public void setId(int id) {
       this.id = id;
    }
    public NamegetName() {
       return name;
    }
    public void setName(Name name) {
       this.name = name;
    }
    public Date getBirthday() {
       return birthday;
    }
    public void setBirthday(Date birthday) {
       this.birthday = birthday;
    }
}
3.映射文件中增加Name类的组件映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hbsi.domain">
    <class name="User" table="user">
       <id name="id" column="id">
                  <generator class="native"/>
       </id>
       <!-- 组件映射 ,在User中有一个Name类 -->
       <component name="name">
           <property name="firstName"column="first_name"></property>
           <property name="lastName"column="last_name"></property>
       </component>
       <property name="birthday" />
    </class>
</hibernate-mapping>
注意:所用的标签是<component></component>
 
第二种:把组件类作为持久化类的集合属性来使用

1. 创建Photo实例类   为组件类的集合属性

package com.hbsi.domain;
public class Photo {
    private String name;
    private String filePath;
    private String description;
    public Photo() {
       super();
       // TODO Auto-generatedconstructor stub
    }
    public String getName() {
       return name;
    }
    public void setName(String name) {
       this.name = name;
    }
    public String getFilePath() {
       return filePath;
    }
    public void setFilePath(String filePath) {
       this.filePath = filePath;
    }
    public String getDescription() {
       return description;
    }
    public void setDescription(String description) {
       this.description = description;
    }
}
2.  创建Album类
package com.hbsi.domain;
import java.util.List;
public class Album {
    private Integer id;
    private String title;
    private String description;
    private List<Photo> photos;
    public Album() {
       super();
       // TODO Auto-generatedconstructor stub
    }
    public IntegergetId() {
       return id;
    }
    public void setId(Integer id) {
       this.id = id;
    }
    public String getTitle() {
       return title;
    }
    public void setTitle(String title) {
       this.title = title;
    }
    public String getDescription() {
       return description;
    }
    public void setDescription(String description) {
       this.description = description;
    }
    public List<Photo> getPhotos() {
       return photos;
    }
    public void setPhotos(List<Photo> photos) {
       this.photos = photos;
    }
}
3. Album的映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hbsi.domain">
    <class name="Album" table="album">
       <id name="id"column="id">
           <generator class="native"/>
       </id>
       <property name="title"/>
       <property name="description"/>
       <!-- 用bag来映射list集合 -->
       <bag name="photos"table="photo">
           <key column="album_id"not-null="true"></key>
<!-- composite合成的意思 即为合成的元素 -->
           <composite-element class="Photo">
              <property name="name"></property>
              <property name="filePath"></property>
              <property name="description"></property>
           </composite-element>
       </bag>
    </class>
</hibernate-mapping>
4. 持久化类
package com.hbsi.test;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hbsi.domain.Album;
importcom.hbsi.domain.Photo;
import com.hbsi.hibernate.utils.HibernateUtil;
public class PhotoAlbum {
    publicstatic void main(String[] args) {
       add();
    }
    staticvoid add() {
       Session session = null;
       Transaction transaction = null;
       try {
           session= HibernateUtil.getSession();
           transaction= session.beginTransaction();
 
           Albumalbum = new Album();
           album.setTitle("熊熊的亮相");
           album.setDescription("老王就是熊熊");
 
           Photophoto = new Photo();
           photo.setName("熊熊纪念册");
           photo.setFilePath("老王宾馆");
           photo.setDescription("熊熊是非常可爱的");
 
           List<Photo>photos = new ArrayList<Photo>();
           photos.add(photo);
 
           album.setPhotos(photos);
 
           session.save(album);
 
           transaction.commit();
 
       }finally {
           if(session != null) {
              session.close();
           }
       }
    }
}
非常提醒:在测试的时候,实例化Album类和Photo类,在插入数据库的时候只插入album即可,而对于photo根本不用保存,因为photo只属于Album类中的一个属性类,没有id等约束,它它只属于一个类的分支,只能通过Album去控制,而不可以单独拿photo来操作,这个问题纠结了我半天啊! 

   
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息