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();
}
} 注意:添加、修改、查詢、刪除數據,這幾步要一步一步來進行測試,即在添加數據時,其他代碼先注釋掉;添加完后在數據庫里查詢結果,然后再解除"修改數據"部分的注釋,就這樣一步步完成測試工作。否則出現意想不到的結果。
只完成"添加數據"后的數據庫中結果:

清空數據庫,同時完成“添加、修改數據”,數據庫中結果:
(可見在修改數據時,刪除了email1,增加了email4)