Hibernate实体关系映射

Hibernate的实体关系映射包括一对多、多对一、多对多这三种类型。

一般前两种是组合使用,成为一个双向多对一映射。(上一篇文章中的情况)

而多对多则分两种情况:

1.多对多只是为了表明二者的联系,不包含其他属性。

2.多对多不只是表明二者联系,而且这个联系也有自身的属性。

如职工Employee和项目Project是多对多的关系。


对于第一种情况,可以直接使用Hibernate的<many-to-many>标签来进行配置,不需要自己建立中间表和对应实体。

Employee:

<span style="font-size:14px;">                private int employee_id;
		private String employee_name;
		private Set<Project> projects = new HashSet<Project>();</span>
Project:
<span style="font-size:14px;">        private int project_id;
	private String project_name;
 	private Set<Employee> employees = new HashSet<Employee>();
</span>


Employee.hbm.xml:

<span style="font-size:14px;">
        <class name = "Employee"  table = "employee">
            <id name = "employee_id" column = "employee_id">
                <generator class = "assigned"/>
            </id>
            <property name = "employee_name"  column = "employee_name"></property>
            <set name = "projects"  table = "pro_emp" cascade="save-update" inverse="true" >
                    <key column = "remployee_id"></key>
                    <many-to-many class = "Project" column="rproject_d"></many-to-many>
            </set>
        </class></span>

Project.hbm.xml:

<span style="font-size:14px;">        <class name="Project" table="project">
		<id name="project_id" column="project_id">
			<generator class="assigned" />
		</id>
		<property name="project_name" column="project_name"></property>
		<set name="employees" table="pro_emp" cascade="save-update" lazy="false">
			<key column="rproject_d"></key>
			<many-to-many class="Employee" column="remployee_id"></many-to-many>
		</set>
	</class></span>
这样就实现了双方的多对多关联,运行后数据库中会生成一个中间表pro_emp,其中有两个属性:rproject和remployee,分别用来保存项目号与职工号。

查询的时候双方都可以查询另一方,如要查询职工号为1的职员工作的项目,可以这样查询:

<span style="font-size:14px;">String hql = "from employee where employee_id = 1";
Query query = session.createQuery(hql);
List list = query.list();
Employee e = (Employee)list.get(0);
Set projects = e.getProjects();
Iterator iter = projects.iterator();
while(iter.hasNext()){
Project p = (Project)iter.Next();
System.out.println(p.getProject_name());
}
</span>
而对于第二种情况则不能简单的使用多对多<many-to-many>标签来配置,而应该自己建立一个中间表及对应的实体,表的字段有双方的主键作为外键,以及联系自身具有的属性。双方分别与中间表建立多对一的联系。

这里同样有两种方式,一是采用联合主键,二是新建一个主键。我采用的是新建一个主键的方式:(假设联系表自身属性为加入项目的时间)

<span style="font-size:14px;">表pro_emp(id,project_id,employee_id,time)</span>

新建一个实体类Pro_Emp:

<span style="font-size:14px;">private int id;
private Project project;
private Employee employee;
private Date time;</span>

Employee:

<span style="font-size:14px;">                private int employee_id;
		private String employee_name;
		private Set<Pro_Emp> projects = new HashSet<Pro_Emp>();</span>
Project:
<span style="font-size:14px;">        private int project_id;
	private String project_name;
 	private Set<Pro_Emp> employees = new HashSet<Pro_Emp>();
</span>

Pro_Emp.hbm.xml:

<span style="font-size:14px;">         <class name="Pro_Emp" table="pro_emp">
		<id name="id" column="id">
			<generator class="assigned" />
		</id>
		<many-to-one name = "project" class = "Project">
                   <column name = "project_id"></column>
</span><pre name="code" class="java"><span style="font-size:14px;">                <many-to-one>
</span><pre name="code" class="java"><span style="font-size:14px;">                <many-to-one name = "employee" class = "Employee">
                   <column name = "employee_id"></column>
</span><pre name="code" class="java"><span style="font-size:14px;">                <many-to-one></span>

 
</class> 
 
 
Employee.hbm.xml: 

<span style="font-size:14px;">        <class name = "Employee"  table = "employee">
            <id name = "employee_id" column = "employee_id">
                <generator class = "assigned"/>
            </id>
            <property name = "employee_name"  column = "employee_name"></property>
            <set name = "projects" cascade="save-update" inverse="true" >
                    <key column = "employee_id"></key>
                    <one-to-many class = "Project" ></one-to-many>
            </set>
        </class></span>
Project.hbm.xml:
<span style="font-size:14px;">       </span><pre name="code" class="java"><span style="font-size:14px;">        <class name="Project" table="project">
		<id name="project_id" column="project_id">
			<generator class="assigned" />
		</id>
		<property name="project_name" column="project_name"></property>
		<set name="employees" cascade="save-update" lazy="false">
			<key column="project_d"></key>
			<one-to-many class="Employee" ></one-to-many>
		</set>
	</class></span>

 
这样就配置好了Employee与Pro_Emp的多对一,以及Project与Pro_Emp的多对一联系。 

在保存一个Pro_Emp联系元组的时候,可以取出一个项目元组和一个职工元组,使用set方法加入到pro_emp的属性中,然后调用session.save(pro_emp)方法将其持久化到数据库中。(具体代码与第一种情况类似,不再贴出来)

总结:大多数的多对多联系都具有自身的属性,这样的话就需要使用拆分的方式,将一个多对多联系拆分为两个多对一。拆分之后还有一个问题就是中间表的主键设置问题,是设置为联合主键还是新建一个主键,这里建议是新建一个主键,因为如果要采用联合主键的方式,在保存的时候只能按照参照主键来设置属性。不够方便。也可能是目前刚接触,对这块而不够了解,采用联合主键可能有其独特的作用,暂且不谈。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值