Hibernate Set集合映射简单例子

jopen 10年前

Hibernate Set集合映射简单例子

用户表(user_set)和电子邮件表(email_set)之间的关系:每个用户可以有多个不同的电子邮件地址,对用户来说,电子邮件就是一个集合,则在用户的实体类中就可以通过定义一个集合类型的属性来表达。

创建两个对应表:

email_set:

create table email_set(  id int(11) not null,  address varchar(100) not null  )engine=innodb default charset=gbk;

user_set:

create table user_set(  id int(11) not null auto_increment,  name varchar(100) not null default '',  primary key(id)  )engine=innodb default charset=gbk;

建立角色实体类UserSet.java:

package collect.set;    import java.util.HashSet;  import java.util.Set;    public class UserSet implements java.io.Serializable {     // Fields     private Integer id;   private String name;   private Set emails = new HashSet();     // Constructors     /** default constructor */   public UserSet() {   }     /** full constructor */   public UserSet(String name) {    this.name = name;   }     // Property accessors     public Integer getId() {    return this.id;   }     public void setId(Integer id) {    this.id = id;   }     public String getName() {    return this.name;   }     public void setName(String name) {    this.name = name;   }     public Set getEmails() {    return emails;   }     public void setEmails(Set emails) {    this.emails = emails;   }     public void addEmail(String email) {    this.emails.add(email);   }     public void removeEmail(String email) {    this.emails.remove(email);   }  }

解析:由于一个user可以有多个电子邮件,而且每个电子邮件不能重复。所以在UserSet类中定义了Set类型的变量,用来保存电子邮件。

建立Set类型的映射文件UserSet.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>  <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  <!--    Mapping file autogenerated by MyEclipse Persistence Tools  -->  <hibernate-mapping>   <class name="collect.set.UserSet" table="user_set" catalog="ssh">    <id name="id" type="java.lang.Integer">     <column name="id" />     <generator class="native" />    </id>    <property name="name" type="java.lang.String">     <column name="name" length="100" not-null="true" />    </property>    <!--Set类型映射-->    <set name="emails" table="email_set">     <key column="id"></key>     <element type="java.lang.String">      <column name="address"></column></element>    </set>   </class>  </hibernate-mapping>

解析:使用set映射元素来关联email_set表,set映射元素的上面几个配置:

name:集合属性的名字。

table:这个集合对应表的名称(在此指定了Set元素对应的表为email_set)。

嵌套的标签<key>和<element>对应表"email_set"中的字段,其中<key>即表email_set的外键(取值为表user_set的主键值)。

对于List集合的话,要多加一个<index>标签来配置List索引。

通过此Set类型映射,当在表user_set中INSERT一条记录时,user_set表中多了一条记录如('1' , 'user1'),这时集合属性emails中添加的元素如email1、email2就会自动对应地(以id='1')INSERT到表email_set中去。对于“修改、删除数据”操作是一样的道理,两表同步完成UPDATE、DELETE操作。

将该映射文件加入到Hibernate配置文件中,建立测试类Test.java:

package collect.set;    import java.util.Iterator;  import org.hibernate.Session;  import org.hibernate.SessionFactory;  import org.hibernate.Transaction;  import org.hibernate.cfg.Configuration;    public class Test {     public static void main(String[] args) {    // Configuration管理Hibernate配置    Configuration config = new Configuration().configure();    // 根据Configuration建立 SessionFactory    // SessionFactory用来建立Session    SessionFactory sessionFactory = config.buildSessionFactory();      // 创建实例    UserSet user1 = new UserSet();    user1.setName("user1");    user1.addEmail("email1");    user1.addEmail("email2");    user1.addEmail("email2");                UserSet user2 = new UserSet();    user2.setName("user2");    user2.addEmail("email3");      // 定义主键变量    Integer pid;      // 添加数据    Session session = sessionFactory.openSession();    Transaction tx = null;    try {     tx = session.beginTransaction();     // 创建主键变量     pid = (Integer) session.save(user1);     session.save(user2);     tx.commit();    } catch (RuntimeException e) {     if (tx != null)      tx.rollback();     throw e;    } finally {     session.close();    }            // 修改数据    session = sessionFactory.openSession();    tx = null;    try {     tx = session.beginTransaction();     user1 = (UserSet) session.get(UserSet.class, pid);     //修改user名字     user1.setName("user1 update");     user1.removeEmail("email1");     user1.addEmail("email4");     session.update(user1);     tx.commit();    } catch (RuntimeException e) {     if (tx != null)      tx.rollback();     throw e;    } finally {     session.close();    }            // 查询数据    session = sessionFactory.openSession();    user1 = (UserSet) session.get(UserSet.class, pid);    System.out.println("user name:" + user1.getName());    Iterator iter = user1.getEmails().iterator();    while (iter.hasNext()) {     System.out.println("email name:" + (String) iter.next());    }    session.close();            // 删除数据    session = sessionFactory.openSession();    tx = null;    try {     tx = session.beginTransaction();     user1 = (UserSet) session.get(UserSet.class, pid);     session.delete(user1);     tx.commit();    } catch (RuntimeException e) {     if (tx != null)      tx.rollback();     throw e;    } finally {     session.close();    }         // 关闭sessionFactory    sessionFactory.close();     }    }

注意:添加、修改、查询、删除数据,这几步要一步一步来进行测试,即在添加数据时,其他代码先注释掉;添加完后在数据库里查询结果,然后再解除"修改数据"部分的注释,就这样一步步完成测试工作。否则出现意想不到的结果。

只完成"添加数据"后的数据库中结果:

Hibernate Set集合映射简单例子

清空数据库,同时完成“添加、修改数据”,数据库中结果:

Hibernate Set集合映射简单例子 (可见在修改数据时,删除了email1,增加了email4)