-
Composite-element映射非常类似于一对多的关系映射,配置Composite-element映射,可以实现简单的一对多关系。
本例中有一个团队(team)和成员(teammembers)表,每一个team都可以拥有多个teammembers,使用Composite-element映射能够完成这种需求。建立两个相关的 数据库表:[sql]create table team(id int(11) not null auto_increment,name varchar(50) default null,primary key(id))engine=innodb default charset=gbk;[sql]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:[java]package collect.composite_element;import java.util.HashMap;import java.util.Map;public class Team implements java.io.Serializable {// Fieldsprivate 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 accessorspublic 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:[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:[ html]<?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>子元素,则一切与原来一样。这也说明了JVM要通过xml文件解析编译类文件。<parent>子元素只是起说明作用,对于此例因为没有用到get/setTeam(),故可省略掉。将该映射文件加入到Hibernate配置文件中,建立一个测试类Test.java:[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用来建立SessionSessionFactory 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();// 关闭sessionFactorysessionFactory.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 name1 team updateteammembers:team_id name age teamrole1 m1 33 程序员1 m3 33 项目经理
Hibernate Composite-element映射的一个简单例子
最新推荐文章于 2017-08-20 18:48:27 发布