一·关联关系(多对多)
举例:一个员工可以开发多个项目,一个项目也可以被多个员工开发
1.1单向
Project实体
public class Project {
private Integer proid;
private String proname;
}
Project.hbm.xml文件
<?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.hibernate.mapping.manytomany.entity">
<class name="Project" table="Project" schema="wy">
<id name="proid" column="proid">
<generator class="native"/>
</id>
<property name="proname" column="proname"></property>
</class>
</hibernate-mapping>
Employee 实体
再该实体中植入项目的实体
public class Employee {
private Integer empid;
private String empname;
private Set<Project> projects = new HashSet<Project>();
}
Employeehbm.xml 文件
<?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.hibernate.mapping.manytomany.entity">
<class name="Employee" table="Employee" schema="wy" lazy="false">
<id name="empid" column="empid">
<generator class="native"/>
</id>
<property name="empname" column="empname"></property>
<set name="projects" table="REmpPro" cascade="save-update">
<key column="REmpNo"></key>
<many-to-many class="Project" column="RProNo"></many-to-many>
</set>
</class>
</hibernate-mapping>
<set>标签:
name:被植入的set集合的属性名
table:多对多的中间表名称
cascade:(级联)当执行修改和添加时hibernate框架会自动将关联的实体做对应的操作
key column:表示中间表中员工的外键
class:set集合中的属性
column:集合中元素在中间表的外键
单测:
@Test
public void add(){
Session session = HibernateUtil.getSession();
Employee emp1=new Employee();
emp1.setEmpname("刘黑子");
Project pro1=new Project();
pro1.setProname("项目1");
Project pro2=new Project();
pro2.setProname("项目2");
emp1.getProjects().add(pro1);
emp1.getProjects().add(pro2);
session.save(emp1);
HibernateUtil.closeSession();
System.out.println("add ok!");
}
1.2双向
在单向的基础上,将项目实体类中也加入员工的实体类集合
修改后的Project 实体
public class Project {
private Integer proid;
private String proname;
private Set<Employee> projects = new HashSet<Employee>();
}
修改后的Project.hbm.xml文件
<?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.hibernate.mapping.manytomany.entity">
<class name="Project" table="Project" schema="wy">
<id name="proid" column="proid">
<generator class="native"/>
</id>
<property name="proname" column="proname"></property>
<set name="employees" table="REmpPro">
<key column="RProNo"></key>
<many-to-many class="Project" column="REmpNo"></many-to-many>
</set>
</class>
</hibernate-mapping>
单测:
@Test
public void sel(){
Session session = HibernateUtil.getSession();
Employee employee = session.get(Employee.class, 6);
for (Project item:employee.getProjects()){
System.out.println(item.getProname());
}
HibernateUtil.closeSession();
System.out.println("sel ok!");
}
二.延迟加载
2.1类级别的延迟加载

立即检索:立即加载检索方法指定的对象,立即发送SQL
延迟检索:延迟加载检索方法指定的对象.在使用具体的属性时,再进行加载,才发送SQL
注意:无论<class>元素的lazy属性是true还是false,Session的get()方法及Query的list()方法在类级别总是使用立即检索策略
同样继续使用上述的实体

将加载方式改为立即加载
单测:
@Test
public void sel(){
Session session = HibernateUtil.getSession();
Employee employee = session.load(Employee.class, 6);
HibernateUtil.closeSession();
System.out.println("sel ok!");
}
结果:

发送了sql

将加载方式修改为延迟加载
单测
@Test
public void sel(){
Session session = HibernateUtil.getSession();
Employee employee = session.load(Employee.class, 6);
HibernateUtil.closeSession();
System.out.println("sel ok!");
}
结果:

没有sql
2.2一对多和多对多的延迟加载

继续使用上述实体

不延迟加载
Debug:
@Test
public void sel(){
Session session = HibernateUtil.getSession();
Employee employee = session.get(Employee.class, 6);
HibernateUtil.closeSession();
System.out.println("sel ok!");
}


加强延迟加载
Debug
Test
public void sel(){
Session session = HibernateUtil.getSession();
Employee employee = session.load(Employee.class, 6);
HibernateUtil.closeSession();
System.out.println("sel ok!");
}
结果:

当访问employee的属性时不会加载其中的set<project>集合。当访问set集合的属性时也不会加载,当访问set集合中元素时才会查询
浙公网安备 33010602011771号