Hibernate Composite-element映射的一个简单例子

来源:互联网 发布:golang beego 编辑:程序博客网 时间:2024/05/17 03:56
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 {  
  
    // 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:
 
[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用来建立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       项目经理
0 0
原创粉丝点击