Hibernate Composite-element映射的一個簡單例子

Composite-element映射非常類似于一對多的關系映射,配置Composite-element映射,可以實現簡單的一對多關系。
本例中有一個團隊(team)和成員(teammembers)表,每一個team都可以擁有多個teammembers,使用Composite-element映射能夠完成這種需求。
建立兩個相關的數據庫表:
create table team( id int(11) not null auto_increment, name varchar(50) default null, primary key(id) )engine=innodb default charset=gbk;
create table teammembers( team_id int(11) default null, name varchar(20) default null, age int(3) default null, teamrole varchar(20) default null )engine=innodb default charset=gbk;
建立實體類Team.java:
package collect.composite_element;
import java.util.HashMap;
import java.util.Map;
public class Team implements java.io.Serializable {
// Fields
private Integer id;
private String name;
private Map memebers=new HashMap();
// Constructors
/** default constructor */
public Team() {
}
/** full constructor */
public Team(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 Map getMemebers() {
return memebers;
}
public void setMemebers(Map memebers) {
this.memebers = memebers;
}
} 建立團隊成員的實體類Member.java:
package collect.composite_element;
import java.io.Serializable;
public class Member {
private String id;
private String name;
private Team team;
private String age;
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
} 建立一個映射文件Team.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>
<import class="collect.composite_element.Member" />
<class name="collect.composite_element.Team" table="team"
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="50" />
</property>
<map name="memebers" table="teammembers">
<key column="team_id"></key>
<map-key column="teamrole" type="java.lang.String"></map-key>
<composite-element class="collect.composite_element.Member">
<parent name="team" />
<property name="name" />
<property name="age"></property>
</composite-element>
</map>
</class>
</hibernate-mapping> “design”視圖:
(注:雙擊所有目錄節點項,都會彈出”Properties”窗口,用來設置相應屬性;在單擊目錄節點后,在右側的屬性設置窗口也可進行相應屬性的設置,非常方便)

注解:映射文件中導入(import)了Member類,使用了map集合映射,key指定了對應的key為team_id,map-key則指定了Map集合元素的索引,這里是teamrole,即團隊角色(這里假定角色不能重復,即key值唯一)。通過上面“design”視圖,可以清楚地看到各屬性層聯關系。
使用composite-element元素(嵌于<map>標簽內)將Map集合中的每個元素映射給teammember的相應字段,這里映射了Member實體類。
<parent>子元素,用來表明composite-element類中的一個屬性是指向包含它的實體的引用。如果在Member類中不去定義Team類型屬性team及相應setter方法,運行時會出現異常:
Exception in thread "main"org.hibernate.PropertyNotFoundException: Could not find a setter for property team in classcollect.composite_element.Member
若同時去掉映射文件中的<parent>子元素以及對Team類型和相應setter方法的定義,則一切與原來一樣。這也說明了JVM要通過xml文件解析編譯類文件。
將該映射文件加入到Hibernate配置文件中,建立一個測試類Test.java:
package collect.composite_element;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import collect.map.UserMap;
public class Test {
public static void main(String[] args) {
// Configuration管理Hibernate配置
Configuration config = new Configuration().configure();
// 根據Configuration建立 SessionFactory
// SessionFactory用來建立Session
SessionFactory sessionFactory = config.buildSessionFactory();
// 創建實例
Team t=new Team();
t.setName("team1");
Member m1=new Member();
m1.setName("m1");
m1.setAge("33");
Member m2=new Member();
m2.setName("m2");
m2.setAge("22");
t.getMemebers().put("程序員", m1);
t.getMemebers().put("測試工程師", m2);
// 定義主鍵變量
Integer pid;
// 添加數據
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 創建主鍵變量
pid = (Integer) session.save(t);
tx.commit();
} catch (RuntimeException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
session.close();
}
// 修改數據
Member m3=new Member();
m3.setName("增加人員");
m3.setAge("33");
session = sessionFactory.openSession();
tx = null;
try {
tx = session.beginTransaction();
t = (Team) session.get(Team.class, pid);
// 修改名字
t.setName("team update");
t.getMemebers().put("項目經理", m3);
t.getMemebers().remove("測試工程師");
session.update(t);
tx.commit();
} catch (RuntimeException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
session.close();
}
// 查詢數據
session = sessionFactory.openSession();
t = (Team) session.get(Team.class, pid);
System.out.println("team name:" + t.getName());
System.out.println("member name:" + t.getMemebers());
session.close();
// 關閉sessionFactory
sessionFactory.close();
}
} 運行結果:
控制臺:
13:38:45,751 DEBUG SQL:346 -insert into ssh.team (name) values (?)
13:38:45,782 DEBUG SQL:346 -insert into teammembers (team_id, teamrole, name, age) values (?, ?, ?, ?)
13:38:45,782 DEBUG SQL:346 - insert intoteammembers (team_id, teamrole, name, age) values (?, ?, ?, ?)
數據庫:
運行添加模塊:

-----------------------------------------------------------------
運行修改模塊:
team:
id name
1 team update
teammembers:
team_id name age teamrole
1 m1 33 程序員
1 m3 33 項目經理
來自:http://blog.csdn.net/itzyjr/article/details/8505830