Hibernate之多表关联
Hibernate的夺标关联有一对多、多对一、多对多。
具体操作如下:
先创建两个表作为关联表,第一个表(EMP)员工,第二个表(DEP)部门表。
Emp字段有empid(员工id) , empname(员工名称),did(部门外键) ;
Dep字段有depid(部门id) ,depname(部门名称) ;
创建bean类:
Dep类
package com.pojo;
import java.util.HashSet;
import java.util.Set;
public class Dep {
private Integer depid ;
private String depname ;
private Set<Emp> emps = new HashSet<Emp>();
public void setEmps(Set<Emp> emps) {
this.emps = emps;
}
public Integer getDepid() {
return depid;
}
public void setDepid(Integer depid) {
this.depid = depid;
}
public String getDepname() {
return depname;
}
public void setDepname(String depname) {
this.depname = depname;
}
public Set<Emp> getEmps() {
return emps;
}
}
Emp类:
package com.pojo;
public class Emp {
private Integer empid ;
private String empname ;
private Dep dep ;
public Dep getDep() {
return dep;
}
public void setDep(Dep dep) {
this.dep = dep;
}
public Integer getEmpid() {
return empid;
}
public void setEmpid(Integer empid) {
this.empid = empid;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
@Override
public String toString() {
return "Emp [empid=" + empid + ", empname=" + empname + ", dep=" + dep
+ "]";
}
}
关联fan方式有两种:
一、多对一关联
多对一关联需要在多的一方创建对象如下:
private Dep dep ;
然后配置映射多的一方的映射文件 —— emp.hbm.xml
<?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">
<hibernate-mapping>
<class name="com.pojo.Emp" table="emp">
<id column="empid" name="empid">
<generator class="assigned"></generator>
</id>
<property name="empname" column="empname"></property>
<many-to-one name="dep" class="com.pojo.Dep" column="did"></many-to-one>
</class>
</hibernate-mapping>
其中<many-to-one/>为多对一的关系标签。name属性填写bean中Dep 的对象 。class熟悉指向一的一方,colunm属性表示外键关联。
运行代码如下:
public void TestManyToOne(){
Configuration configuration = new Configuration().configure("hibernate.cfg.xml") ;
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Emp emp = new Emp() ;
emp.setEmpid(2);
emp.setEmpname("李er");
Dep dep = new Dep();
dep.setDepid(2);
dep.setDepname("小小部");
emp.setDep(dep);
session.save(emp);
session.save(dep);
transaction.commit();
session.close();
}
二、一对多的关联
首先需要创建一个set集合用来关联多的一方的对象
private Set<Emp> emps = new HashSet<Emp>();
然后配置映射文件——dep.hbm.xml
<?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">
<hibernate-mapping>
<class name="com.pojo.Dep" table="dep">
<id column="depid" name="depid">
<generator class="assigned"></generator>
</id>
<property name="depname" column="depname"></property>
<set name="emps">
<key column="did"></key>
<one-to-many class="com.pojo.Emp" />
</set>
</class>
</hibernate-mapping>
关键在<set/>标签中,这里不赘述。
测试代码:
public void TestOneTOMany(){
Configuration configuration = new Configuration().configure();
SessionFactory factory = configuration.buildSessionFactory();
Session session = factory.openSession();
Dep dep = (Dep) session.get(Dep.class, 1) ;
Set<Emp> emps = dep.getEmps() ;
for (Emp emp : emps) {
System.out.println(emp);
}
session.close();
}
在获取数据库对象有两个方法:
1. session.load() ——懒加载,调用就加载。
- 这种方式总是会返回一个代理而不是真正得去查询数据库。 在Hibernate里面,代理是一个依据ID值获取到的对象,该对象的属性还没有初始化,它看起来就是一个临时的虚拟对象而已。
- 如果load方法没有找到数据,就会抛出ObjectNotFoundException.
2. session.get() ——立即加载,不管调不调用,都加载。
- 这种方式总是会去数据库查询数据并返回一个真实的对象,该对象就代表数据库中的一行而非代理。
- 如果没有找到数据就会返回null.