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