hibernate中的一对多,多对一关系实在是令人头疼得很,今天就来详细叙述一
下这两种关系
hibernate中的多对一关系,我们以员工和部门的关系来说明
显然,多个员工可以对应一个部门,对于员工来讲是多对一关系,orm中,
Employee中有个属性是private Department depart,而在映射文件中该属性不能
用简单属性来表示,由于对于员工是多对一关系,故在员工的映射文件中,
hibernate用<many-to-one />标签来表示,该标签中有属性name,表示属性的名
字(多对一里面的‘一’),在这里是depart,column可以指定该属性在表中的字
段名,我们在这里指定depart_id,默认就是depart字段,depart字段其实就是
private Department depart中depart的id,表关系上即为外键
外键,not-null属性表示该字段是否可以为空
我们在保存实体的时候,先保存depart,这样在数据表中生成depart的id才能作
为外键给每一个employee使用,再保存employee.这种方式没有update语句,因
为在保存employee的时候外键已经知道了,就是depart的id
而如果先保存employee(如果在上面not-null指定为true,则会报错,因为在保
存employee的时候外键还是空的),再保存depart的时候,会生成update语句,
因为保存完depart后生成depart的id作为外键更新到employee表中去了
我们在查询的时候,查询employee,由于employee中有depart的引用,故会将
depart的信息一并查出来,只不过是通过代理的方式查出来的,hibernate中使
用的延迟加载技术,故如果不使用depart的话,是没有查询depart的sql语句的
,而只有使用到depart,即通过employee.getDepart()的时候才会真正的去查询
,当然使用depart的前提是session不关闭!
hibernate中的一对多关系,我们以部门和员工的关系来说明
从部门的角度看,部门和员工是一对多关系,即一个depart中有很多employee,
在实体上表示为private Set<Employee> emps,而在映射文件上,hibernate用
<set/>标签来表示,set中有个属性是name,表示set的属性名,即emps,由于是
一对多关系,故set中有个节点<one-to-many/>,在此标签中有属性class表示一
对多对应的那个多是什么类,在这里当然是Employee,我们在查询depart的时候
,要将emp一并查出来,所以必须告诉hibernate是根据emp中的那个字段来查询
的,在这里显然是depart_id,故在查询emp的时候,可以通过select * from emp
where depart_id=id,这里的id是depart表中的主键id
保存和查询和多对一是一样的,唯一不同的是在下面一种情况,查询depart的时
候可以将emps一并查出来,不过这里也是通过代理对象来查的,方式同上面叙述
的一致
为什么我们要用双向关联呢???
由于任何一方都有其他一方的引用,这样我们就可以通过任何一方查到其他一方
的所有信息(当然也可以手工查询,不过实在是太麻烦了,还不如去用jdbc呢),
业务中也经常会有这种需求,举个简单的例子,要查询某个学生成绩,通过学生
可以将它的每一门课程成绩一并查出来,完全是由Hibernate帮我们完成的,要
查询生物是90分这个分数段的学生,也可以只查询这门学科,就可以将所有满足
要求的学生都查出来!