hibernate关联关系
①.第一种关联关系:一对多
一对多:是最普遍的映射关系,简单来讲就如部门与员工的关系。"一对多"从部门的角度来说一个部门可以有多个员工,即为一对多。
一对多关系在hbm文件中的配置信息:
部门(一方):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package声明pojo类所在的包,如果不写 那么在class中需要指明pojo类所在的包
schema指数据库模式 一个模式下可以有多张表
-->
<hibernate-mapping package="cn.jjz.pojo.onetomany">
<!-- class指映射一个实体类entity
提供了公共的无参构造方法-通过反射产生对象
属性用private修饰,并且生成对应的get/set方法
类不能用final来修饰-hibernate会产生代理类(cglib)
类需要指明标识
name表示pojo类名
table表示pojo类对应数据库中的表名;如果不写默认是类名
-->
<class name="cn.jjz.pojo.onetomany.Dept" table="Dept">
<id name="deptno" column="deptno">
<generator class="native"></generator>
</id>
<property name="deptname" column="deptname"></property>
<set name="emps" cascade="save-update" inverse="true">
<!--多的一方表的外键列-->
<key column="deptno"></key>
<one-to-many class="cn.jjz.pojo.onetomany.Emps"></one-to-many>
</set>
</class>
</hibernate-mapping>
员工(多方):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package声明pojo类所在的包,如果不写 那么在class中需要指明pojo类所在的包
schema指数据库模式 一个模式下可以有多张表
-->
<hibernate-mapping package="cn.jjz.pojo.onetomany">
<!-- class指映射一个实体类entity
提供了公共的无参构造方法-通过反射产生对象
属性用private修饰,并且生成对应的get/set方法
类不能用final来修饰-hibernate会产生代理类(cglib)
类需要指明标识
name表示pojo类名
table表示pojo类对应数据库中的表名;如果不写默认是类名
-->
<class name="cn.jjz.pojo.onetomany.Emps" table="Emps">
<id name="eid" column="empid">
<generator class="native"></generator>
</id>
<property name="ename" column="ename"></property>
<!--多对一-->
<many-to-one name="dept" column="deptno" class="cn.jjz.pojo.onetomany.Dept"></many-to-one>
</class>
</hibernate-mapping>
实例所示:
②.第二种关联关系:多对一
多对一:从员工的角度来说多个员工可以对应一个部门,即为多对一。
多对一关系在hbm文件中的配置信息:
员工(多):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package声明pojo类所在的包,如果不写 那么在class中需要指明pojo类所在的包
schema指数据库模式 一个模式下可以有多张表
-->
<hibernate-mapping package="cn.jjz.pojo.manytoone">
<!-- class指映射一个实体类entity
提供了公共的无参构造方法-通过反射产生对象
属性用private修饰,并且生成对应的get/set方法
类不能用final来修饰-hibernate会产生代理类(cglib)
类需要指明标识
name表示pojo类名
table表示pojo类对应数据库中的表名;如果不写默认是类名
-->
<class name="Emps" table="Emps">
<id name="eid" column="empid">
<generator class="native"></generator>
</id>
<property name="ename" column="ename"></property>
<!--多对一 -->
<many-to-one name="dept" column="deptno" class="Dept"></many-to-one>
</class>
</hibernate-mapping>
部门(一):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package声明pojo类所在的包,如果不写 那么在class中需要指明pojo类所在的包
schema指数据库模式 一个模式下可以有多张表
-->
<hibernate-mapping package="cn.jjz.pojo.manytoone">
<!-- class指映射一个实体类entity
提供了公共的无参构造方法-通过反射产生对象
属性用private修饰,并且生成对应的get/set方法
类不能用final来修饰-hibernate会产生代理类(cglib)
类需要指明标识
name表示pojo类名
table表示pojo类对应数据库中的表名;如果不写默认是类名
-->
<class name="Dept" table="Dept">
<id name="deptno" column="deptno">
<generator class="sequence"></generator>
</id>
<property name="deptname" column="deptname"></property>
</class>
</hibernate-mapping>
实例所示:
③.第三种关联关联:多对多
多对多:相当于程序员于项目的关系,一个程序员可以有参与多个项目工程,一个项目工程能有多个程序员参与。
多对多关系在hbm文件中的配置信息:
程序员:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.jjz.pojo.manytomany">
<class name="Employee" table="Employee">
<id name="empid" column="empid">
<generator class="native"></generator>
</id>
<property name="empname" />
<!--table指的是中间表-->
<set name="projects" table="PROEMP">
<key column="REMPID"></key>
<many-to-many column="RPROID" class="Project"></many-to-many>
</set>
</class>
</hibernate-mapping>
项目工程:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.jjz.pojo.manytomany">
<class name="Project" table="Project">
<id name="proid" column="proid">
<generator class="native"></generator>
</id>
<property name="proname" />
<!--table指的是中间表-->
<set name="employees" table="PROEMP" cascade="save-update" inverse="true">
<key column="RPROID"></key>
<many-to-many column="REMPID" class="Employee"></many-to-many>
</set>
</class>
</hibernate-mapping>
其实多对多就是两个一对多,它的配置没什么新奇的相对于一对多。在多对多的关系设计中,一般都会使用一个中间表将他们拆分成两个一对多。<set>标签中的"table"属性就是用于指定中间表的。中间表一般包含两个表的主键值,该表用于存储两表之间的关系。由于被拆成了两个一对多,中间表是多方,它是使用外键关联的,<key>是用于指定外键的,用于从中间表取出相应的数据。中间表每一行数据只包含了两个关系表的主键,要获取与自己关联的对象集合,还需要取出由外键所获得的记录中的另一个主键值,由它到对应的表中取出数据,填充到集合中。<many-to-many>中的"column"属性是用于指定按那一列的值获取对应的数据。
例如用project表来说,它与employee表使用一个中间表proemp关联。如果要获取project记录对应的项目工程,首先需要使用外键"proid"从proemp表中取得相应的数据,然后在取得的数据中使用"rempid"列的值,在employee表中检索出相关的程序员数据。其实,为了便于理解,你可以在使用project表的使用就把中间表看成是employee表,反之亦然。这样就可以使用一对多的思维来理解了,多方关联一方需要外键那么在本例子中就需要"proid"来关联。
实例所示: