Hibernate(四) 关联关系(多对多)和延迟加载

it2026-03-12  5

一·关联关系(多对多)

举例:一个员工可以开发多个项目,一个项目也可以被多个员工开发

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还是falseSessionget()方法及Querylist()方法在类级别总是使用立即检索策略

 

同样继续使用上述的实体

将加载方式改为立即加载

单测:

@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:

@Testpublic 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集合中元素时才会查询

 

转载于:https://www.cnblogs.com/wy0119/p/8150436.html

最新回复(0)