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)